mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-11-03 23:22:59 +00:00 
			
		
		
		
	Compare commits
	
		
			658 Commits
		
	
	
		
			v1.80pr1.7
			...
			v1.16.2-1.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					7809a2eddd | ||
| 
						 | 
					183b342071 | ||
| 
						 | 
					0bb5515055 | ||
| 
						 | 
					e8e9294fdf | ||
| 
						 | 
					9acfc0316f | ||
| 
						 | 
					29fb0baa09 | ||
| 
						 | 
					d5de39ebd4 | ||
| 
						 | 
					0faf76e4bd | ||
| 
						 | 
					99581e1f40 | ||
| 
						 | 
					e8e2ed9fe5 | ||
| 
						 | 
					9f72448ecd | ||
| 
						 | 
					3da3f16deb | ||
| 
						 | 
					0e2ce3c634 | ||
| 
						 | 
					fe00e00537 | ||
| 
						 | 
					29646a7f61 | ||
| 
						 | 
					50d2712581 | ||
| 
						 | 
					3093f882d8 | ||
| 
						 | 
					e5cf0d1c61 | ||
| 
						 | 
					cd879b067f | ||
| 
						 | 
					053cb1b53c | ||
| 
						 | 
					6b102a8142 | ||
| 
						 | 
					ac7979fb46 | ||
| 
						 | 
					c8a6888a2f | ||
| 
						 | 
					9ce33f8a3f | ||
| 
						 | 
					d51851e763 | ||
| 
						 | 
					fb70a1a998 | ||
| 
						 | 
					a1dcd59d95 | ||
| 
						 | 
					2a17585702 | ||
| 
						 | 
					2f323f23d7 | ||
| 
						 | 
					087c305b0d | ||
| 
						 | 
					31764f6d65 | ||
| 
						 | 
					4efde2b294 | ||
| 
						 | 
					95554a53d1 | ||
| 
						 | 
					89c1b2771d | ||
| 
						 | 
					8f069a9b72 | ||
| 
						 | 
					2e9d6603e3 | ||
| 
						 | 
					46595e73df | ||
| 
						 | 
					a6a1b9b8e5 | ||
| 
						 | 
					3f277a7a7b | ||
| 
						 | 
					90c5d3f1e8 | ||
| 
						 | 
					a5f7cf8334 | ||
| 
						 | 
					3075f89797 | ||
| 
						 | 
					45297665c6 | ||
| 
						 | 
					ddbf3fc111 | ||
| 
						 | 
					da82b89676 | ||
| 
						 | 
					d5f1a2c817 | ||
| 
						 | 
					6020adef6b | ||
| 
						 | 
					d2a52a8b5d | ||
| 
						 | 
					9f8774960f | ||
| 
						 | 
					36bb8b67c9 | ||
| 
						 | 
					8f3a56dd32 | ||
| 
						 | 
					113d5d982f | ||
| 
						 | 
					37a447e745 | ||
| 
						 | 
					9e2232d240 | ||
| 
						 | 
					514db30fb1 | ||
| 
						 | 
					08181f72d4 | ||
| 
						 | 
					613a28a5af | ||
| 
						 | 
					e4c422d6f9 | ||
| 
						 | 
					478f992dea | ||
| 
						 | 
					b54519d0e6 | ||
| 
						 | 
					9499654757 | ||
| 
						 | 
					c5138c535c | ||
| 
						 | 
					5bd8d84d14 | ||
| 
						 | 
					ab0310e27c | ||
| 
						 | 
					607751da40 | ||
| 
						 | 
					1efabccd14 | ||
| 
						 | 
					029374e9aa | ||
| 
						 | 
					2a8efb3fd5 | ||
| 
						 | 
					48edcde4ef | ||
| 
						 | 
					58a2995bbc | ||
| 
						 | 
					a35dcb28ef | ||
| 
						 | 
					7b2d482387 | ||
| 
						 | 
					2b077554f7 | ||
| 
						 | 
					9134f243c1 | ||
| 
						 | 
					c0f3ca81fb | ||
| 
						 | 
					190ed4fd20 | ||
| 
						 | 
					b9ff9b7f90 | ||
| 
						 | 
					b9b8121be9 | ||
| 
						 | 
					014bf55cd4 | ||
| 
						 | 
					085ae2e74a | ||
| 
						 | 
					4ff33f165d | ||
| 
						 | 
					d929c02d2a | ||
| 
						 | 
					d50a08a549 | ||
| 
						 | 
					c493d668c8 | ||
| 
						 | 
					53477fd3a1 | ||
| 
						 | 
					87aa839b60 | ||
| 
						 | 
					e02ccdcb1a | ||
| 
						 | 
					f36f532c63 | ||
| 
						 | 
					5a816917d5 | ||
| 
						 | 
					7af63d052d | ||
| 
						 | 
					4f8217d1ab | ||
| 
						 | 
					5409d441b5 | ||
| 
						 | 
					d5f82fa458 | ||
| 
						 | 
					d0deab3519 | ||
| 
						 | 
					d5a8df753a | ||
| 
						 | 
					13de2c4dd0 | ||
| 
						 | 
					906280225e | ||
| 
						 | 
					161a5b4707 | ||
| 
						 | 
					c6b6b4479c | ||
| 
						 | 
					96e7b60285 | ||
| 
						 | 
					086fccd997 | ||
| 
						 | 
					5dfaf6eee9 | ||
| 
						 | 
					e251dd066c | ||
| 
						 | 
					9abcfe56ea | ||
| 
						 | 
					abbc641fd4 | ||
| 
						 | 
					c60dcb4f5a | ||
| 
						 | 
					4be0b15afa | ||
| 
						 | 
					a4ae36b6b3 | ||
| 
						 | 
					ac075d9f53 | ||
| 
						 | 
					05d7be0362 | ||
| 
						 | 
					9a71dc1a26 | ||
| 
						 | 
					156023b154 | ||
| 
						 | 
					6b3773a862 | ||
| 
						 | 
					376d628cf0 | ||
| 
						 | 
					44062ebd52 | ||
| 
						 | 
					5739285fc2 | ||
| 
						 | 
					70b457ed18 | ||
| 
						 | 
					ca2995ed38 | ||
| 
						 | 
					6816931659 | ||
| 
						 | 
					1547ecbeb3 | ||
| 
						 | 
					e918f55b58 | ||
| 
						 | 
					c28b468844 | ||
| 
						 | 
					052cf8ee7d | ||
| 
						 | 
					550ada2f9e | ||
| 
						 | 
					17b7727262 | ||
| 
						 | 
					4553e404b2 | ||
| 
						 | 
					a565a571f9 | ||
| 
						 | 
					fb64b6017b | ||
| 
						 | 
					ed4229ab70 | ||
| 
						 | 
					3fb906ef6c | ||
| 
						 | 
					e1663f3df0 | ||
| 
						 | 
					52c6584c81 | ||
| 
						 | 
					9f87eda5de | ||
| 
						 | 
					697e9449cf | ||
| 
						 | 
					76c3e4c155 | ||
| 
						 | 
					358289b5f9 | ||
| 
						 | 
					5eec24676f | ||
| 
						 | 
					f52b8fa2de | ||
| 
						 | 
					447c3ab125 | ||
| 
						 | 
					8fac68386e | ||
| 
						 | 
					a3021c4697 | ||
| 
						 | 
					b7c61f9c6d | ||
| 
						 | 
					08a0342618 | ||
| 
						 | 
					3d7a81696d | ||
| 
						 | 
					48cb032ddf | ||
| 
						 | 
					33260a7747 | ||
| 
						 | 
					a049502d12 | ||
| 
						 | 
					ae7ef66dfa | ||
| 
						 | 
					9748679484 | ||
| 
						 | 
					da419b24e7 | ||
| 
						 | 
					7f57a977a1 | ||
| 
						 | 
					2f42a4e85b | ||
| 
						 | 
					af40f5ae5c | ||
| 
						 | 
					759d02a249 | ||
| 
						 | 
					d7729337ac | ||
| 
						 | 
					ee391ae9ea | ||
| 
						 | 
					4ed4a6409b | ||
| 
						 | 
					e5cc345f49 | ||
| 
						 | 
					d847a4d9e0 | ||
| 
						 | 
					f106733d71 | ||
| 
						 | 
					f3de97d67f | ||
| 
						 | 
					544f276ff0 | ||
| 
						 | 
					463635a459 | ||
| 
						 | 
					3b7b845930 | ||
| 
						 | 
					1fc0214857 | ||
| 
						 | 
					11bf601db9 | ||
| 
						 | 
					7c1154ddfc | ||
| 
						 | 
					df557e03fa | ||
| 
						 | 
					524b6f1d8a | ||
| 
						 | 
					cea8be7efa | ||
| 
						 | 
					c5f918ad95 | ||
| 
						 | 
					b14c7842fc | ||
| 
						 | 
					eead8b5755 | ||
| 
						 | 
					10a27a7a25 | ||
| 
						 | 
					865fc239a0 | ||
| 
						 | 
					f9f94b8304 | ||
| 
						 | 
					cb8135a0d1 | ||
| 
						 | 
					ef4b0a5632 | ||
| 
						 | 
					6a6a87489c | ||
| 
						 | 
					2360a6e951 | ||
| 
						 | 
					f4f71185ae | ||
| 
						 | 
					062977336a | ||
| 
						 | 
					e52d98ad8b | ||
| 
						 | 
					ef8da8054f | ||
| 
						 | 
					1ccd687c00 | ||
| 
						 | 
					a8ce5a5b20 | ||
| 
						 | 
					68e6bc464b | ||
| 
						 | 
					68762fe84c | ||
| 
						 | 
					419f29321a | ||
| 
						 | 
					00b41d29c1 | ||
| 
						 | 
					0ffd5fcf85 | ||
| 
						 | 
					95fee95006 | ||
| 
						 | 
					239bd769df | ||
| 
						 | 
					b4e0e9984f | ||
| 
						 | 
					79f42e35ce | ||
| 
						 | 
					be89fc25f9 | ||
| 
						 | 
					8eae02c037 | ||
| 
						 | 
					930fd59298 | ||
| 
						 | 
					bf13bac152 | ||
| 
						 | 
					649acbae1c | ||
| 
						 | 
					05eada427b | ||
| 
						 | 
					03caf9d805 | ||
| 
						 | 
					d6ea3aab1c | ||
| 
						 | 
					f3a330e330 | ||
| 
						 | 
					044d2b2b06 | ||
| 
						 | 
					fb440b0d2e | ||
| 
						 | 
					0de5969ec1 | ||
| 
						 | 
					3f98b2785e | ||
| 
						 | 
					798868427e | ||
| 
						 | 
					c79f643ba7 | ||
| 
						 | 
					1db3a14c54 | ||
| 
						 | 
					bf6d017ad1 | ||
| 
						 | 
					8b1773dd60 | ||
| 
						 | 
					a706300598 | ||
| 
						 | 
					2541c3c5e6 | ||
| 
						 | 
					41a1b99f7d | ||
| 
						 | 
					1862a439e2 | ||
| 
						 | 
					018ecfbaa0 | ||
| 
						 | 
					4c8fd4fc35 | ||
| 
						 | 
					35c1b10224 | ||
| 
						 | 
					c1c01bef7c | ||
| 
						 | 
					a48c3d0ba8 | ||
| 
						 | 
					93a9ebc4f6 | ||
| 
						 | 
					7cc2bd43c6 | ||
| 
						 | 
					393e628721 | ||
| 
						 | 
					0bcd28e58c | ||
| 
						 | 
					42f5389fb8 | ||
| 
						 | 
					041cfe91b4 | ||
| 
						 | 
					0f82a4589b | ||
| 
						 | 
					4320a4f851 | ||
| 
						 | 
					037cbabb32 | ||
| 
						 | 
					0dde859582 | ||
| 
						 | 
					e59c043fb6 | ||
| 
						 | 
					ae928c4397 | ||
| 
						 | 
					da41c65128 | ||
| 
						 | 
					4d18234714 | ||
| 
						 | 
					d254c6464b | ||
| 
						 | 
					3a5d50e572 | ||
| 
						 | 
					03b6d2f1ab | ||
| 
						 | 
					b0397ed3c5 | ||
| 
						 | 
					fa70ebcac2 | ||
| 
						 | 
					86e0330100 | ||
| 
						 | 
					92567b4d7e | ||
| 
						 | 
					0ae70fed13 | ||
| 
						 | 
					3b7300543a | ||
| 
						 | 
					642351af1a | ||
| 
						 | 
					121802a683 | ||
| 
						 | 
					08cf55e55f | ||
| 
						 | 
					3c8c0d78ef | ||
| 
						 | 
					c4d18aa9ca | ||
| 
						 | 
					2d4a87adc9 | ||
| 
						 | 
					bedac71e3d | ||
| 
						 | 
					ee4e42e730 | ||
| 
						 | 
					0de75f05dd | ||
| 
						 | 
					be6dd21e54 | ||
| 
						 | 
					927ddb0bde | ||
| 
						 | 
					a8fadabaf1 | ||
| 
						 | 
					44d0f78c1b | ||
| 
						 | 
					38f9a015ca | ||
| 
						 | 
					c311cdc6f5 | ||
| 
						 | 
					a93e0f3284 | ||
| 
						 | 
					14b3065ba4 | ||
| 
						 | 
					3ea2d6a0a8 | ||
| 
						 | 
					c802290437 | ||
| 
						 | 
					f7781defe5 | ||
| 
						 | 
					418420523a | ||
| 
						 | 
					d342a1f368 | ||
| 
						 | 
					81f85361d5 | ||
| 
						 | 
					f1621b30ec | ||
| 
						 | 
					d4f6a594b6 | ||
| 
						 | 
					ff5ba5c131 | ||
| 
						 | 
					4243f30308 | ||
| 
						 | 
					813e91073d | ||
| 
						 | 
					7250f22ff6 | ||
| 
						 | 
					db31a53bba | ||
| 
						 | 
					3023f235a4 | ||
| 
						 | 
					79cd8b4da5 | ||
| 
						 | 
					8e4d311cd9 | ||
| 
						 | 
					9bd8c86a94 | ||
| 
						 | 
					cbc0c1d0b6 | ||
| 
						 | 
					49c37857d4 | ||
| 
						 | 
					b1139a4bf6 | ||
| 
						 | 
					7e8559278e | ||
| 
						 | 
					1e7f1c98fc | ||
| 
						 | 
					a802f25dd6 | ||
| 
						 | 
					f1d6d21d6d | ||
| 
						 | 
					a80302c513 | ||
| 
						 | 
					1c46949da7 | ||
| 
						 | 
					07a56454a0 | ||
| 
						 | 
					a0e72d02c8 | ||
| 
						 | 
					455a59ca85 | ||
| 
						 | 
					46d78af068 | ||
| 
						 | 
					08d22fd3df | ||
| 
						 | 
					e6c691a8f8 | ||
| 
						 | 
					4b0e5c445c | ||
| 
						 | 
					eb5cff1045 | ||
| 
						 | 
					35c7792aa2 | ||
| 
						 | 
					521688d630 | ||
| 
						 | 
					75e2845c01 | ||
| 
						 | 
					2f96283286 | ||
| 
						 | 
					cbe6e9b5f5 | ||
| 
						 | 
					2ab79cf474 | ||
| 
						 | 
					6ce34aba79 | ||
| 
						 | 
					5eeb320b60 | ||
| 
						 | 
					93310850d2 | ||
| 
						 | 
					a2880b12ca | ||
| 
						 | 
					cef2657048 | ||
| 
						 | 
					ccd85eb055 | ||
| 
						 | 
					303b57779a | ||
| 
						 | 
					6279816ecc | ||
| 
						 | 
					4ae77261fa | ||
| 
						 | 
					4b7d843b78 | ||
| 
						 | 
					1c28df65c3 | ||
| 
						 | 
					85b740f484 | ||
| 
						 | 
					f9929cb27d | ||
| 
						 | 
					bafab1ac07 | ||
| 
						 | 
					e05c262468 | ||
| 
						 | 
					acfb72246c | ||
| 
						 | 
					9d51c4c340 | ||
| 
						 | 
					18068effec | ||
| 
						 | 
					7a3f7d3bba | ||
| 
						 | 
					95aa48c456 | ||
| 
						 | 
					6ea8ca991b | ||
| 
						 | 
					f1e551b960 | ||
| 
						 | 
					772c54ec74 | ||
| 
						 | 
					13cb789c18 | ||
| 
						 | 
					42220c4268 | ||
| 
						 | 
					3052506e2e | ||
| 
						 | 
					0741daa7eb | ||
| 
						 | 
					b4aa554279 | ||
| 
						 | 
					8fe2abe0ae | ||
| 
						 | 
					5af789ae11 | ||
| 
						 | 
					904a168d5c | ||
| 
						 | 
					724441eddc | ||
| 
						 | 
					f68ab3edd1 | ||
| 
						 | 
					68542aca3a | ||
| 
						 | 
					594bc4203c | ||
| 
						 | 
					57318b022d | ||
| 
						 | 
					761159aa93 | ||
| 
						 | 
					29dce26bf6 | ||
| 
						 | 
					717ab69093 | ||
| 
						 | 
					138a2cf08f | ||
| 
						 | 
					81daf82647 | ||
| 
						 | 
					f3798bfb63 | ||
| 
						 | 
					bc07dfad2e | ||
| 
						 | 
					8dd1c2a6cc | ||
| 
						 | 
					d10b657a54 | ||
| 
						 | 
					f90da739eb | ||
| 
						 | 
					d9cadf64e8 | ||
| 
						 | 
					15d4a55cd8 | ||
| 
						 | 
					309cbdb8be | ||
| 
						 | 
					39a9ad0ce7 | ||
| 
						 | 
					0f3c44c926 | ||
| 
						 | 
					a0e7c4a74c | ||
| 
						 | 
					7d428030df | ||
| 
						 | 
					00c395f689 | ||
| 
						 | 
					d8e1c73d26 | ||
| 
						 | 
					ffa4cc241b | ||
| 
						 | 
					6f1b740c8f | ||
| 
						 | 
					3406ba3ebf | ||
| 
						 | 
					b6715bd812 | ||
| 
						 | 
					18aee02221 | ||
| 
						 | 
					401bbf2e6a | ||
| 
						 | 
					7467b7f88a | ||
| 
						 | 
					c82d8a7c2a | ||
| 
						 | 
					6b81bcf334 | ||
| 
						 | 
					3d67421d98 | ||
| 
						 | 
					acac70675d | ||
| 
						 | 
					56434259c1 | ||
| 
						 | 
					da7e4b9016 | ||
| 
						 | 
					d4b8650d21 | ||
| 
						 | 
					17645a79f0 | ||
| 
						 | 
					ce1f14a010 | ||
| 
						 | 
					43050426de | ||
| 
						 | 
					b05f60c98b | ||
| 
						 | 
					c44c560f96 | ||
| 
						 | 
					e839ef54af | ||
| 
						 | 
					0cb659d78c | ||
| 
						 | 
					9048deeb95 | ||
| 
						 | 
					5592ebae7d | ||
| 
						 | 
					b076c32fd1 | ||
| 
						 | 
					a48f1e310f | ||
| 
						 | 
					19aca001d7 | ||
| 
						 | 
					114f913bf8 | ||
| 
						 | 
					1c9810890a | ||
| 
						 | 
					b11beb508b | ||
| 
						 | 
					af8d4da594 | ||
| 
						 | 
					a81db2cda6 | ||
| 
						 | 
					99bdff0f92 | ||
| 
						 | 
					bb138326df | ||
| 
						 | 
					5b0ce7410d | ||
| 
						 | 
					d5ea22d1a0 | ||
| 
						 | 
					210f3fa9e2 | ||
| 
						 | 
					d661cfa88b | ||
| 
						 | 
					68bf3a71dc | ||
| 
						 | 
					3cdb12d293 | ||
| 
						 | 
					ad33acd7d1 | ||
| 
						 | 
					0ec3884e98 | ||
| 
						 | 
					7f2471d6b2 | ||
| 
						 | 
					e0660b1dab | ||
| 
						 | 
					2182cfbeb7 | ||
| 
						 | 
					8fafec4915 | ||
| 
						 | 
					b9fd690ecb | ||
| 
						 | 
					2f2ada4416 | ||
| 
						 | 
					9c951c58d9 | ||
| 
						 | 
					4b4b47e231 | ||
| 
						 | 
					2c027adb68 | ||
| 
						 | 
					4a25e7a178 | ||
| 
						 | 
					55d54fec63 | ||
| 
						 | 
					220e4bd660 | ||
| 
						 | 
					978c28a686 | ||
| 
						 | 
					b867ada5e5 | ||
| 
						 | 
					7071cc972b | ||
| 
						 | 
					6898f932a0 | ||
| 
						 | 
					2e0ef6385d | ||
| 
						 | 
					f93da7ea51 | ||
| 
						 | 
					1210bb8a4d | ||
| 
						 | 
					48a71e96eb | ||
| 
						 | 
					3bf47b5290 | ||
| 
						 | 
					9e9f199e55 | ||
| 
						 | 
					5a8a111857 | ||
| 
						 | 
					48ba247ab4 | ||
| 
						 | 
					362dbd97ac | ||
| 
						 | 
					aa0e1883d1 | ||
| 
						 | 
					9cdbcb4332 | ||
| 
						 | 
					23ddd4feb5 | ||
| 
						 | 
					fcaa777c95 | ||
| 
						 | 
					b195cab6a7 | ||
| 
						 | 
					63dc0daa09 | ||
| 
						 | 
					34602ec4be | ||
| 
						 | 
					f3ce44042f | ||
| 
						 | 
					4205f18f0c | ||
| 
						 | 
					6be330ae8d | ||
| 
						 | 
					4569af2130 | ||
| 
						 | 
					765c31315a | ||
| 
						 | 
					0e191e42a0 | ||
| 
						 | 
					ca34b2a1b8 | ||
| 
						 | 
					7afc3e5260 | ||
| 
						 | 
					f9e13ca67a | ||
| 
						 | 
					810258e9b8 | ||
| 
						 | 
					5e462adc5c | ||
| 
						 | 
					1fd0b40776 | ||
| 
						 | 
					2965fb666f | ||
| 
						 | 
					390575ab4d | ||
| 
						 | 
					e4ef92ca2d | ||
| 
						 | 
					9bf586b018 | ||
| 
						 | 
					173ea72001 | ||
| 
						 | 
					1230cabcb0 | ||
| 
						 | 
					6ed03e1fcd | ||
| 
						 | 
					c4b371b124 | ||
| 
						 | 
					a600213b00 | ||
| 
						 | 
					7799b8d4cb | ||
| 
						 | 
					245bf26480 | ||
| 
						 | 
					5d05205d69 | ||
| 
						 | 
					853e2622a1 | ||
| 
						 | 
					d0bf9e9cd7 | ||
| 
						 | 
					7a7951ae68 | ||
| 
						 | 
					bd28955c8e | ||
| 
						 | 
					e46f09a939 | ||
| 
						 | 
					71b1f8138d | ||
| 
						 | 
					1d82a1c98c | ||
| 
						 | 
					b5f60f3f11 | ||
| 
						 | 
					259665d9f1 | ||
| 
						 | 
					ba823bae13 | ||
| 
						 | 
					1290a4402c | ||
| 
						 | 
					379076a5e2 | ||
| 
						 | 
					d12bdf50d8 | ||
| 
						 | 
					cbfd5aeeee | ||
| 
						 | 
					41429bdc0b | ||
| 
						 | 
					54b9966feb | ||
| 
						 | 
					105c66127c | ||
| 
						 | 
					765ad0bd3f | ||
| 
						 | 
					dd05478483 | ||
| 
						 | 
					5d028dea39 | ||
| 
						 | 
					629c51d260 | ||
| 
						 | 
					9ea57961af | ||
| 
						 | 
					07b9b1c9c7 | ||
| 
						 | 
					5b942ff9c1 | ||
| 
						 | 
					7b5a918941 | ||
| 
						 | 
					47721bf76b | ||
| 
						 | 
					35ce0974cd | ||
| 
						 | 
					52e1906d42 | ||
| 
						 | 
					eaf24a3ceb | ||
| 
						 | 
					62760e371e | ||
| 
						 | 
					e154e11186 | ||
| 
						 | 
					72d079ef61 | ||
| 
						 | 
					0bfb7049b0 | ||
| 
						 | 
					f7cb526793 | ||
| 
						 | 
					e34e833d3d | ||
| 
						 | 
					a125a19728 | ||
| 
						 | 
					b3e6a53868 | ||
| 
						 | 
					218f8e53bb | ||
| 
						 | 
					d02575528b | ||
| 
						 | 
					c78adb2cdc | ||
| 
						 | 
					3e28f79ce9 | ||
| 
						 | 
					67af7a698b | ||
| 
						 | 
					06e76f9b15 | ||
| 
						 | 
					6d383d005c | ||
| 
						 | 
					c373583723 | ||
| 
						 | 
					f1d10809d5 | ||
| 
						 | 
					474f571798 | ||
| 
						 | 
					fb9c125ab8 | ||
| 
						 | 
					162fb37421 | ||
| 
						 | 
					d953f031f0 | ||
| 
						 | 
					7fde89ad95 | ||
| 
						 | 
					bd04a93ffb | ||
| 
						 | 
					e2bfaafe28 | ||
| 
						 | 
					1fb3d16b89 | ||
| 
						 | 
					35645b3d93 | ||
| 
						 | 
					a4cd1fe77d | ||
| 
						 | 
					4145914024 | ||
| 
						 | 
					6bd11a5e4a | ||
| 
						 | 
					46fa798797 | ||
| 
						 | 
					70a226207e | ||
| 
						 | 
					257a35f3ed | ||
| 
						 | 
					af01b9514b | ||
| 
						 | 
					070fd1f2ff | ||
| 
						 | 
					fb59da2b06 | ||
| 
						 | 
					11e4d0de82 | ||
| 
						 | 
					e46ab1e267 | ||
| 
						 | 
					d6e0f368df | ||
| 
						 | 
					9f2884bc0f | ||
| 
						 | 
					18d468e887 | ||
| 
						 | 
					63f6735bb8 | ||
| 
						 | 
					ab6f0ccd16 | ||
| 
						 | 
					ae0f093e73 | ||
| 
						 | 
					e5f988e3fe | ||
| 
						 | 
					12e82afad2 | ||
| 
						 | 
					6c2db93cbd | ||
| 
						 | 
					d5edbe700b | ||
| 
						 | 
					86ad43c3ab | ||
| 
						 | 
					f450c0156b | ||
| 
						 | 
					8abcfcb4ac | ||
| 
						 | 
					f3cace1d03 | ||
| 
						 | 
					e1e5e898ab | ||
| 
						 | 
					3aa3852ff6 | ||
| 
						 | 
					709a6329c7 | ||
| 
						 | 
					c9f05a2939 | ||
| 
						 | 
					e41377f862 | ||
| 
						 | 
					d173787a94 | ||
| 
						 | 
					d5aea26f3a | ||
| 
						 | 
					2681e578c4 | ||
| 
						 | 
					1f498dcc73 | ||
| 
						 | 
					83b01d35eb | ||
| 
						 | 
					8a7e651c99 | ||
| 
						 | 
					80a5759bae | ||
| 
						 | 
					e8a4fbb4e3 | ||
| 
						 | 
					0ce67afcc1 | ||
| 
						 | 
					a8dad23fa3 | ||
| 
						 | 
					443e0f8f76 | ||
| 
						 | 
					a838595e1e | ||
| 
						 | 
					61daab910e | ||
| 
						 | 
					7fd19c43e9 | ||
| 
						 | 
					ce0685c31f | ||
| 
						 | 
					e33f852baa | ||
| 
						 | 
					227d5e9e69 | ||
| 
						 | 
					1c648850ab | ||
| 
						 | 
					63691707fc | ||
| 
						 | 
					5d97b9c8f3 | ||
| 
						 | 
					77666d7399 | ||
| 
						 | 
					ed69495b03 | ||
| 
						 | 
					66b61d4e9e | ||
| 
						 | 
					8dd084ac5c | ||
| 
						 | 
					932f8a44fc | ||
| 
						 | 
					101b3500cc | ||
| 
						 | 
					a777801e15 | ||
| 
						 | 
					0d6787641a | ||
| 
						 | 
					744bba300e | ||
| 
						 | 
					34d43d8273 | ||
| 
						 | 
					7bc9745c7a | ||
| 
						 | 
					b414cba681 | ||
| 
						 | 
					1c9110b927 | ||
| 
						 | 
					325459e336 | ||
| 
						 | 
					ee3347afbd | ||
| 
						 | 
					27aaec9a82 | ||
| 
						 | 
					929f23fd2d | ||
| 
						 | 
					8422a40c69 | ||
| 
						 | 
					ca334e7e5c | ||
| 
						 | 
					54acf1d087 | ||
| 
						 | 
					42d3901ee3 | ||
| 
						 | 
					f8b328a048 | ||
| 
						 | 
					41a320e9a4 | ||
| 
						 | 
					57fb77d7fe | ||
| 
						 | 
					b59dcbfc0e | ||
| 
						 | 
					618c534d81 | ||
| 
						 | 
					26ba61097b | ||
| 
						 | 
					2c87e66db8 | ||
| 
						 | 
					f61f7df2d8 | ||
| 
						 | 
					364d31465e | ||
| 
						 | 
					4c7ac50dd8 | ||
| 
						 | 
					37e25136ed | ||
| 
						 | 
					d9f03f3ec7 | ||
| 
						 | 
					4d5c52bc63 | ||
| 
						 | 
					a1c4a9fb58 | ||
| 
						 | 
					031f17c98e | ||
| 
						 | 
					4ead319092 | ||
| 
						 | 
					dd6bab5413 | ||
| 
						 | 
					5b48a0fa5f | ||
| 
						 | 
					2032e7a83a | ||
| 
						 | 
					72b9d3d802 | ||
| 
						 | 
					70cb8ae16c | ||
| 
						 | 
					05a97a4f12 | ||
| 
						 | 
					8b86a954ee | ||
| 
						 | 
					741ee447ca | ||
| 
						 | 
					3537f49ced | ||
| 
						 | 
					c3e4a4de5e | ||
| 
						 | 
					86569533e9 | ||
| 
						 | 
					e6850ab644 | ||
| 
						 | 
					97c2421a22 | ||
| 
						 | 
					f765b6a487 | ||
| 
						 | 
					3e6f6467af | ||
| 
						 | 
					7e6eb62504 | ||
| 
						 | 
					949b71d40c | ||
| 
						 | 
					afdfcb21b7 | ||
| 
						 | 
					776a786e1b | ||
| 
						 | 
					8ae65d1bdd | ||
| 
						 | 
					0829506176 | ||
| 
						 | 
					71ee692da0 | ||
| 
						 | 
					acd0092ed5 | ||
| 
						 | 
					1160ffbf9e | ||
| 
						 | 
					93cb6547bd | ||
| 
						 | 
					f9c91f288f | ||
| 
						 | 
					62cf921cc6 | ||
| 
						 | 
					4bd7381827 | ||
| 
						 | 
					43459ec825 | ||
| 
						 | 
					5fa01f8b96 | ||
| 
						 | 
					67d5693d2a | ||
| 
						 | 
					c2a782afa4 | ||
| 
						 | 
					14c9558ee6 | ||
| 
						 | 
					d53a73e7e7 | ||
| 
						 | 
					7e334bd4a5 | ||
| 
						 | 
					51e787f631 | ||
| 
						 | 
					8080699030 | ||
| 
						 | 
					e555f9f7f0 | ||
| 
						 | 
					822db6e9b5 | ||
| 
						 | 
					ac1f30ef43 | ||
| 
						 | 
					0fc1b8c46b | ||
| 
						 | 
					e7c19bcf55 | ||
| 
						 | 
					63ca8aca4c | ||
| 
						 | 
					2caa9c57fc | ||
| 
						 | 
					33fad2da15 | ||
| 
						 | 
					518eefbe10 | ||
| 
						 | 
					1ba73454c1 | ||
| 
						 | 
					ee4735c17c | ||
| 
						 | 
					b008edae90 | ||
| 
						 | 
					c6bd88f3ad | ||
| 
						 | 
					efa57521c7 | ||
| 
						 | 
					4700f8831b | ||
| 
						 | 
					9428bee316 | ||
| 
						 | 
					89c7183a1d | ||
| 
						 | 
					d2a9e7e458 | ||
| 
						 | 
					1774f1a079 | ||
| 
						 | 
					de1307913b | ||
| 
						 | 
					093132533d | ||
| 
						 | 
					0685be6bfa | ||
| 
						 | 
					f40733e9a6 | ||
| 
						 | 
					a3d1cff298 | ||
| 
						 | 
					b8957cab5c | 
@@ -5,13 +5,18 @@ indent_style = space
 | 
			
		||||
indent_size = 4
 | 
			
		||||
end_of_line = lf
 | 
			
		||||
charset = utf-8
 | 
			
		||||
# Sadly too many files have whitespace errors, so we leave this as is for
 | 
			
		||||
# now and just make sure we don't introduce any more.
 | 
			
		||||
# trim_trailing_whitespace = true
 | 
			
		||||
trim_trailing_whitespace = true
 | 
			
		||||
insert_final_newline = true
 | 
			
		||||
 | 
			
		||||
[*.md]
 | 
			
		||||
trim_trailing_whitespace = false
 | 
			
		||||
 | 
			
		||||
[*.sexp]
 | 
			
		||||
indent_size = 2
 | 
			
		||||
 | 
			
		||||
[*.yml]
 | 
			
		||||
indent_size = 2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[*.properties]
 | 
			
		||||
insert_final_newline = false
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
# Ignore changes in generated files
 | 
			
		||||
src/generated/resources/data/** linguist-generated
 | 
			
		||||
							
								
								
									
										16
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
---
 | 
			
		||||
name: Bug report
 | 
			
		||||
about: Report some misbehaviour in the mod
 | 
			
		||||
labels: bug
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
<!--
 | 
			
		||||
## Before reporting
 | 
			
		||||
 - Search for the bug on the issue tracker. Make sure to look at closed issues too!
 | 
			
		||||
-->
 | 
			
		||||
 | 
			
		||||
## Useful information to include:
 | 
			
		||||
 - Minecraft version
 | 
			
		||||
 - CC: Tweaked version
 | 
			
		||||
 - Logs: These will be located in the `logs/` directory of your Minecraft instance. Please upload them as a gist or directly into this editor.
 | 
			
		||||
 - Detailed reproduction steps: sometimes I can spot a bug pretty easily, but often it's much more obscure. The more information I have to help reproduce it, the quicker it'll get fixed.
 | 
			
		||||
							
								
								
									
										14
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
---
 | 
			
		||||
name: Feature request
 | 
			
		||||
about: Suggest an idea or improvement
 | 
			
		||||
labels: enhancement
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
<!--
 | 
			
		||||
## Before reporting
 | 
			
		||||
 - Search for the suggestion here. It's possible someone's suggested it before!
 | 
			
		||||
-->
 | 
			
		||||
 | 
			
		||||
## Useful information to include:
 | 
			
		||||
 - Explanation of how the feature/change should work.
 | 
			
		||||
 - Some rationale/use case for a feature. My general approach to designing new features is to ask yourself "what issue are we trying to solve" and _then_ "is this the best way to solve this issue?".
 | 
			
		||||
							
								
								
									
										3
									
								
								.github/pull_request_template.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.github/pull_request_template.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
## A quick checklist
 | 
			
		||||
 - If there's a existing issue, please link to it. If not, provide fill out the same information you would in a normal issue - reproduction steps for bugs, rationale for use-case.
 | 
			
		||||
 - If you're working on CraftOS, try to write a few test cases so we can ensure everything continues to work in the future. Tests live in `src/test/resources/test-rom/spec` and can be run with `./gradlew check`.
 | 
			
		||||
							
								
								
									
										49
									
								
								.github/workflows/main-ci.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								.github/workflows/main-ci.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
name: Build
 | 
			
		||||
 | 
			
		||||
on: [push, pull_request]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    name: Build
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
    - uses: actions/checkout@v2
 | 
			
		||||
 | 
			
		||||
    - name: Set up Java 8
 | 
			
		||||
      uses: actions/setup-java@v1
 | 
			
		||||
      with:
 | 
			
		||||
        java-version: 8
 | 
			
		||||
 | 
			
		||||
    - name: Cache gradle dependencies
 | 
			
		||||
      uses: actions/cache@v1
 | 
			
		||||
      with:
 | 
			
		||||
        path: ~/.gradle/caches
 | 
			
		||||
        key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}
 | 
			
		||||
        restore-keys: |
 | 
			
		||||
          ${{ runner.os }}-gradle-
 | 
			
		||||
 | 
			
		||||
    - name: Build with Gradle
 | 
			
		||||
      run: ./gradlew build --no-daemon || ./gradlew build --no-daemon
 | 
			
		||||
 | 
			
		||||
    - name: Upload Jar
 | 
			
		||||
      uses: actions/upload-artifact@v1
 | 
			
		||||
      with:
 | 
			
		||||
        name: CC-Tweaked
 | 
			
		||||
        path: build/libs
 | 
			
		||||
 | 
			
		||||
    - name: Upload Coverage
 | 
			
		||||
      run: bash <(curl -s https://codecov.io/bash)
 | 
			
		||||
 | 
			
		||||
    - name: Generate Java documentation stubs
 | 
			
		||||
      run: ./gradlew luaJavadoc --no-daemon
 | 
			
		||||
 | 
			
		||||
    - name: Lint Lua code
 | 
			
		||||
      run: |
 | 
			
		||||
        test -d bin || mkdir bin
 | 
			
		||||
        test -f bin/illuaminate || wget -q -Obin/illuaminate https://squiddev.cc/illuaminate/linux-x86-64/illuaminate
 | 
			
		||||
        chmod +x bin/illuaminate
 | 
			
		||||
        bin/illuaminate lint
 | 
			
		||||
 | 
			
		||||
    - name: Check whitespace
 | 
			
		||||
      run: python3 tools/check-lines.py
 | 
			
		||||
							
								
								
									
										16
									
								
								.github/workflows/make-doc.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										16
									
								
								.github/workflows/make-doc.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
set -eu
 | 
			
		||||
 | 
			
		||||
DEST="${GITHUB_REF#refs/*/}"
 | 
			
		||||
echo "Uploading docs to https://tweaked.cc/$DEST"
 | 
			
		||||
 | 
			
		||||
# Setup ssh key
 | 
			
		||||
mkdir -p "$HOME/.ssh/"
 | 
			
		||||
echo "$SSH_KEY" > "$HOME/.ssh/key"
 | 
			
		||||
chmod 600 "$HOME/.ssh/key"
 | 
			
		||||
 | 
			
		||||
# And upload
 | 
			
		||||
rsync -avc -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no -p $SSH_PORT" \
 | 
			
		||||
      "$GITHUB_WORKSPACE/doc/" \
 | 
			
		||||
      "$SSH_USER@$SSH_HOST:/var/www/tweaked.cc/$DEST"
 | 
			
		||||
							
								
								
									
										52
									
								
								.github/workflows/make-doc.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								.github/workflows/make-doc.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
name: Build documentation
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
    - master
 | 
			
		||||
    - mc-1.15.x
 | 
			
		||||
    tags:
 | 
			
		||||
  release:
 | 
			
		||||
    types: [ published ]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  make_doc:
 | 
			
		||||
    name: Build
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
    - uses: actions/checkout@v1
 | 
			
		||||
 | 
			
		||||
    - name: Set up Java 8
 | 
			
		||||
      uses: actions/setup-java@v1
 | 
			
		||||
      with:
 | 
			
		||||
        java-version: 8
 | 
			
		||||
 | 
			
		||||
    - name: Cache gradle dependencies
 | 
			
		||||
      uses: actions/cache@v1
 | 
			
		||||
      with:
 | 
			
		||||
        path: ~/.gradle/caches
 | 
			
		||||
        key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}
 | 
			
		||||
        restore-keys: |
 | 
			
		||||
          ${{ runner.os }}-gradle-
 | 
			
		||||
 | 
			
		||||
    - name: Build with Gradle
 | 
			
		||||
      run: ./gradlew compileJava --no-daemon || ./gradlew compileJava --no-daemon
 | 
			
		||||
 | 
			
		||||
    - name: Generate Java documentation stubs
 | 
			
		||||
      run: ./gradlew luaJavadoc --no-daemon
 | 
			
		||||
 | 
			
		||||
    - name: Build documentation
 | 
			
		||||
      run: |
 | 
			
		||||
        test -d bin || mkdir bin
 | 
			
		||||
        test -f bin/illuaminate || wget -q -Obin/illuaminate https://squiddev.cc/illuaminate/linux-x86-64/illuaminate
 | 
			
		||||
        chmod +x bin/illuaminate
 | 
			
		||||
        bin/illuaminate doc-gen
 | 
			
		||||
 | 
			
		||||
    - name: Upload documentation
 | 
			
		||||
      run: .github/workflows/make-doc.sh 2> /dev/null
 | 
			
		||||
      env:
 | 
			
		||||
        SSH_KEY:  ${{ secrets.SSH_KEY  }}
 | 
			
		||||
        SSH_USER: ${{ secrets.SSH_USER }}
 | 
			
		||||
        SSH_HOST: ${{ secrets.SSH_HOST }}
 | 
			
		||||
        SSH_PORT: ${{ secrets.SSH_PORT }}
 | 
			
		||||
							
								
								
									
										28
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,12 +1,28 @@
 | 
			
		||||
build
 | 
			
		||||
out
 | 
			
		||||
run
 | 
			
		||||
deploy
 | 
			
		||||
# Build directories
 | 
			
		||||
/classes
 | 
			
		||||
/logs
 | 
			
		||||
/build
 | 
			
		||||
/out
 | 
			
		||||
/doc/**/*.html
 | 
			
		||||
/doc/javadoc/
 | 
			
		||||
/doc/index.json
 | 
			
		||||
 | 
			
		||||
# Runtime directories
 | 
			
		||||
/run
 | 
			
		||||
/run-*
 | 
			
		||||
/test-files
 | 
			
		||||
 | 
			
		||||
*.ipr
 | 
			
		||||
*.iws
 | 
			
		||||
*.iml
 | 
			
		||||
.idea
 | 
			
		||||
.gradle
 | 
			
		||||
luaj-2.0.3/lib
 | 
			
		||||
luaj-2.0.3/*.jar
 | 
			
		||||
*.DS_Store
 | 
			
		||||
 | 
			
		||||
.classpath
 | 
			
		||||
.project
 | 
			
		||||
.settings/
 | 
			
		||||
bin/
 | 
			
		||||
*.launch
 | 
			
		||||
 | 
			
		||||
/src/generated/resources/.cache
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								.travis.yml
									
									
									
									
									
								
							@@ -1,14 +0,0 @@
 | 
			
		||||
language: java
 | 
			
		||||
 | 
			
		||||
script: ./gradlew build --no-daemon
 | 
			
		||||
 | 
			
		||||
before_cache:
 | 
			
		||||
  - rm -f  $HOME/.gradle/caches/modules-2/modules-2.lock
 | 
			
		||||
  - rm -fr $HOME/.gradle/caches/*/plugin-resolution/
 | 
			
		||||
cache:
 | 
			
		||||
  directories:
 | 
			
		||||
    - $HOME/.gradle/caches/
 | 
			
		||||
    - $HOME/.gradle/wrapper/s
 | 
			
		||||
 | 
			
		||||
jdk:
 | 
			
		||||
    - oraclejdk8
 | 
			
		||||
							
								
								
									
										41
									
								
								CONTRIBUTING.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								CONTRIBUTING.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
# Contributing to CC: Tweaked
 | 
			
		||||
As with many open source projects, CC: Tweaked thrives on contributions from other people! This document (hopefully)
 | 
			
		||||
provides an introduction as to how to get started in helping out.
 | 
			
		||||
 | 
			
		||||
If you've any other questions, [just ask the community][community] or [open an issue][new-issue].
 | 
			
		||||
 | 
			
		||||
## Reporting issues
 | 
			
		||||
If you have a bug, suggestion, or other feedback, the best thing to do is [file an issue][new-issue]. When doing so,
 | 
			
		||||
do use the issue templates - they provide a useful hint on what information to provide.
 | 
			
		||||
 | 
			
		||||
## Developing
 | 
			
		||||
In order to develop CC: Tweaked, you'll need to download the source code and then run it. This is a pretty simple
 | 
			
		||||
process. When building on Windows, Use `gradlew.bat` instead of `./gradlew`.
 | 
			
		||||
 | 
			
		||||
 - **Clone the repository:** `git clone https://github.com/SquidDev-CC/CC-Tweaked.git && cd CC-Tweaked`
 | 
			
		||||
 - **Setup Forge:** `./gradlew build`
 | 
			
		||||
 - **Run Minecraft:** `./gradlew runClient` (or run the `GradleStart` class from your IDE).
 | 
			
		||||
 | 
			
		||||
If you want to run CC:T in a normal Minecraft instance, run `./gradlew build` and copy the `.jar` from `build/libs`.
 | 
			
		||||
These commands may take a few minutes to run the first time, as the environment is set up, but should be much faster
 | 
			
		||||
afterwards.
 | 
			
		||||
 | 
			
		||||
### Code linters
 | 
			
		||||
CC: Tweaked uses a couple of "linters" on its source code, to enforce a consistent style across the project. While these
 | 
			
		||||
are run whenever you submit a PR, it's often useful to run this before committing.
 | 
			
		||||
 | 
			
		||||
 - **[Checkstyle]:** Checks Java code to ensure it is consistently formatted. This can be run with `./gradlew build` or
 | 
			
		||||
   `./gradle check`.
 | 
			
		||||
 - **[illuaminate]:** Checks Lua code for semantic and styleistic issues. See [the usage section][illuaminate-usage] for
 | 
			
		||||
   how to download and run it.
 | 
			
		||||
 | 
			
		||||
## Translations
 | 
			
		||||
Translations are managed through [Weblate], an online interface for managing language strings. This is synced
 | 
			
		||||
automatically with GitHub, so please don't submit PRs adding/changing translations!
 | 
			
		||||
 | 
			
		||||
[new-issue]: https://github.com/SquidDev-CC/CC-Tweaked/issues/new/choose "Create a new issue"
 | 
			
		||||
[community]: README.md#Community "Get in touch with the community."
 | 
			
		||||
[checkstyle]: https://checkstyle.org/
 | 
			
		||||
[illuaminate]: https://github.com/SquidDev/illuaminate/
 | 
			
		||||
[illuaminate-usage]: https://github.com/SquidDev/illuaminate/blob/master/README.md#usage
 | 
			
		||||
[weblate]: https://i18n.tweaked.cc/projects/cc-tweaked/minecraft/
 | 
			
		||||
							
								
								
									
										19
									
								
								LICENSE-luaj
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								LICENSE-luaj
									
									
									
									
									
								
							@@ -1,19 +0,0 @@
 | 
			
		||||
Copyright (c) 2007 LuaJ. All rights reserved.
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
							
								
								
									
										80
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								README.md
									
									
									
									
									
								
							@@ -1,33 +1,35 @@
 | 
			
		||||
# 
 | 
			
		||||
[](https://travis-ci.org/SquidDev-CC/CC-Tweaked)
 | 
			
		||||
# 
 | 
			
		||||
[](https://github.com/SquidDev-CC/CC-Tweaked/actions "Current build status") [](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
 | 
			
		||||
 | 
			
		||||
CC: Tweaked is a fork of ComputerCraft which aims to provide earlier access to the more experimental and in-development
 | 
			
		||||
features of the mod. For a more stable experience, I recommend checking out the
 | 
			
		||||
[original mod](https://github.com/dan200/ComputerCraft).
 | 
			
		||||
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
 | 
			
		||||
turtles and more to Minecraft.
 | 
			
		||||
 | 
			
		||||
## What?
 | 
			
		||||
CC: Tweaked (or CC:T for short) does not aim to create a competing fork of ComputerCraft, nor am I planning to take it
 | 
			
		||||
in in a vastly different direction to the original mod. In fact, CC:T aims to be a nurturing ground for various
 | 
			
		||||
features, with a pull request against the original mod being the end goal.
 | 
			
		||||
ComputerCraft has always held a fond place in my heart: it's the mod which really got me into Minecraft, and it's the
 | 
			
		||||
mod which has kept me playing it for many years. However, development of the original mod has slowed, as the original
 | 
			
		||||
developers have had less time to work on the mod, and moved onto other projects and commitments.
 | 
			
		||||
 | 
			
		||||
CC:T also includes many pull requests from the community which have not yet been merged, offering a large number
 | 
			
		||||
of additional bug fixes and features over the original mod.
 | 
			
		||||
CC: Tweaked (or CC:T for short) is an attempt to continue ComputerCraft's legacy. It's not intended to be a competitor
 | 
			
		||||
to CC, nor do I want to take it in a vastly different direction to the original mod. Instead, CC:T focuses on making the
 | 
			
		||||
ComputerCraft experience as _solid_ as possible, ironing out any wrinkles that may have developed over time.
 | 
			
		||||
 | 
			
		||||
## Features
 | 
			
		||||
CC: Tweaked contains the all features of the latest alpha, as well as numerous fixes, performance improvements and
 | 
			
		||||
several additional features. I'd recommend checking out [the releases page](https://github.com/SquidDev-CC/CC-Tweaked/releases)
 | 
			
		||||
to see the full changes, but here's a couple of the more interesting changes:
 | 
			
		||||
CC: Tweaked contains all the features of the latest version of ComputerCraft, as well as numerous fixes, performance
 | 
			
		||||
improvements and several nifty additions. I'd recommend checking out [the releases page](https://github.com/SquidDev-CC/CC-Tweaked/releases)
 | 
			
		||||
to see the full set of changes, but here's a couple of the more interesting additions:
 | 
			
		||||
 | 
			
		||||
 - Replace LuaJ with Cobalt.
 | 
			
		||||
 - Allow running multiple computers at the same time.
 | 
			
		||||
 - Websocket support in the HTTP library.
 | 
			
		||||
 - Wired modems and cables act more like multiparts.
 | 
			
		||||
 - Add map-like rendering for pocket computers and printed pages/books.
 | 
			
		||||
 - Adds the `/computercraft` command, offering various diagnostic tools for server owners. This allows operators to
 | 
			
		||||
   track which computers are hogging resources, turn on and shutdown multiple computers at once and interact with
 | 
			
		||||
   computers remotely.
 | 
			
		||||
 - Add full-block wired modems, allowing one to wrap non-solid peripherals (such as turtles, or chests if Plethora is
 | 
			
		||||
 - Improvements to the `http` library, including websockets, support for other HTTP methods (`PUT`, `DELETE`, etc...)
 | 
			
		||||
   and configurable limits on HTTP usage.
 | 
			
		||||
 - Full-block wired modems, allowing one to wrap non-solid peripherals (such as turtles, or chests if Plethora is
 | 
			
		||||
   installed).
 | 
			
		||||
 - Pocket computers can be held like maps, allowing you to view the screen without entering a GUI.
 | 
			
		||||
 - Printed pages and books can be placed in item frames and held like maps.
 | 
			
		||||
 - Several profiling and administration tools for server owners, via the `/computercraft` command. This allows operators
 | 
			
		||||
   to track which computers are hogging resources, turn on and shutdown multiple computers at once and interact with
 | 
			
		||||
   computers remotely.
 | 
			
		||||
 - Closer emulation of standard Lua, adding the `debug` and `io` libraries. This also enables seeking within binary
 | 
			
		||||
   files, meaning you don't need to read large files into memory.
 | 
			
		||||
 - Allow running multiple computers on multiple threads, reducing latency on worlds with many computers.
 | 
			
		||||
 | 
			
		||||
## Relation to CCTweaks?
 | 
			
		||||
This mod has nothing to do with CCTweaks, though there is no denying the name is a throwback to it. That being said,
 | 
			
		||||
@@ -35,13 +37,33 @@ several features have been included, such as full block modems, the Cobalt runti
 | 
			
		||||
computers.
 | 
			
		||||
 | 
			
		||||
## Contributing
 | 
			
		||||
Any contribution is welcome, be that using the mod, reporting bugs or contributing code. If you do wish to contribute
 | 
			
		||||
code, do consider submitting it to the ComputerCraft repository instead.
 | 
			
		||||
Any contribution is welcome, be that using the mod, reporting bugs or contributing code. If you want to get started
 | 
			
		||||
developing the mod, [check out the instructions here](CONTRIBUTING.md#developing).
 | 
			
		||||
 | 
			
		||||
That being said, in order to start helping develop CC:T, you'll need to follow these steps:
 | 
			
		||||
## Community
 | 
			
		||||
If you need help getting started with CC: Tweaked, want to show off your latest project, or just want to chat about
 | 
			
		||||
ComputerCraft we have a [forum](https://forums.computercraft.cc/) and [Discord guild](https://discord.computercraft.cc)!
 | 
			
		||||
There's also a fairly populated, albeit quiet [IRC channel](http://webchat.esper.net/?channels=computercraft), if that's
 | 
			
		||||
more your cup of tea.
 | 
			
		||||
 | 
			
		||||
 - **Clone the repository:** `git clone https://github.com/SquidDev-CC/CC-Tweaked.git && cd CC-Tweaked`
 | 
			
		||||
 - **Setup Forge:** `./gradlew setupDecompWorkspace`
 | 
			
		||||
 - **Test your changes:** `./gradlew runClient` (or run the `GradleStart` class from your IDE).
 | 
			
		||||
I'd generally recommend you don't contact me directly (email, DM, etc...) unless absolutely necessary (i.e. in order to
 | 
			
		||||
report exploits). You'll get a far quicker response if you ask the whole community!
 | 
			
		||||
 | 
			
		||||
If you want to run CC:T in a normal Minecraft instance, run `./gradlew build` and copy the `.jar` from `build/libs`.
 | 
			
		||||
## Using
 | 
			
		||||
If you want to depend on CC: Tweaked, we have a maven repo. However, you should be wary that some functionality is only
 | 
			
		||||
exposed by CC:T's API and not vanilla ComputerCraft. If you wish to support all variations of ComputerCraft, I recommend
 | 
			
		||||
using [cc.crzd.me's maven](https://cc.crzd.me/maven/) instead.
 | 
			
		||||
 | 
			
		||||
```groovy
 | 
			
		||||
dependencies {
 | 
			
		||||
  maven { url 'https://squiddev.cc/maven/' }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
  implementation fg.deobf("org.squiddev:cc-tweaked-${mc_version}:${cct_version}")
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
You should also be careful to only use classes within the `dan200.computercraft.api` package. Non-API classes are
 | 
			
		||||
subject to change at any point. If you depend on functionality outside the API, file an issue, and we can look into
 | 
			
		||||
exposing more features.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										456
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										456
									
								
								build.gradle
									
									
									
									
									
								
							@@ -1,54 +1,96 @@
 | 
			
		||||
 | 
			
		||||
// For those who want the bleeding edge
 | 
			
		||||
buildscript {
 | 
			
		||||
    repositories {
 | 
			
		||||
        jcenter()
 | 
			
		||||
        mavenCentral()
 | 
			
		||||
        maven {
 | 
			
		||||
            name = "forge"
 | 
			
		||||
            url = "http://files.minecraftforge.net/maven"
 | 
			
		||||
            url = "https://files.minecraftforge.net/maven"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    dependencies {
 | 
			
		||||
        classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
 | 
			
		||||
        classpath 'org.ajoberstar:gradle-git:1.6.0'
 | 
			
		||||
        classpath 'com.google.code.gson:gson:2.8.1'
 | 
			
		||||
        classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.181'
 | 
			
		||||
        classpath 'net.sf.proguard:proguard-gradle:6.1.0beta2'
 | 
			
		||||
        classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0'
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
plugins {
 | 
			
		||||
    id 'com.matthewprenger.cursegradle' version '1.0.10'
 | 
			
		||||
    id "checkstyle"
 | 
			
		||||
    id "jacoco"
 | 
			
		||||
    id "com.github.hierynomus.license" version "0.15.0"
 | 
			
		||||
    id "com.matthewprenger.cursegradle" version "1.3.0"
 | 
			
		||||
    id "com.github.breadmoirai.github-release" version "2.2.4"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
apply plugin: 'net.minecraftforge.gradle.forge'
 | 
			
		||||
apply plugin: 'net.minecraftforge.gradle'
 | 
			
		||||
apply plugin: 'org.ajoberstar.grgit'
 | 
			
		||||
apply plugin: 'maven-publish'
 | 
			
		||||
apply plugin: 'maven'
 | 
			
		||||
 | 
			
		||||
version = "1.80pr1.7"
 | 
			
		||||
version = mod_version
 | 
			
		||||
 | 
			
		||||
group = "org.squiddev"
 | 
			
		||||
archivesBaseName = "cc-tweaked"
 | 
			
		||||
archivesBaseName = "cc-tweaked-${mc_version}"
 | 
			
		||||
 | 
			
		||||
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
 | 
			
		||||
 | 
			
		||||
minecraft {
 | 
			
		||||
    version = "1.12.2-14.23.2.2634"
 | 
			
		||||
    runDir = "run"
 | 
			
		||||
    replace '${version}', project.version
 | 
			
		||||
    runs {
 | 
			
		||||
        client {
 | 
			
		||||
            workingDirectory project.file('run')
 | 
			
		||||
            property 'forge.logging.markers', 'REGISTRIES'
 | 
			
		||||
            property 'forge.logging.console.level', 'debug'
 | 
			
		||||
 | 
			
		||||
    // the mappings can be changed at any time, and must be in the following format.
 | 
			
		||||
    // snapshot_YYYYMMDD   snapshot are built nightly.
 | 
			
		||||
    // stable_#            stables are built at the discretion of the MCP team.
 | 
			
		||||
    // Use non-default mappings at your own risk. they may not allways work.
 | 
			
		||||
    // simply re-run your setup task after changing the mappings to update your workspace.
 | 
			
		||||
    mappings = "snapshot_20180324"
 | 
			
		||||
    // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
 | 
			
		||||
            mods {
 | 
			
		||||
                computercraft {
 | 
			
		||||
                    source sourceSets.main
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        server {
 | 
			
		||||
            workingDirectory project.file("run/server-${mc_version}")
 | 
			
		||||
            property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP'
 | 
			
		||||
            property 'forge.logging.console.level', 'debug'
 | 
			
		||||
 | 
			
		||||
            mods {
 | 
			
		||||
                computercraft {
 | 
			
		||||
                    source sourceSets.main
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        data {
 | 
			
		||||
            workingDirectory project.file('run')
 | 
			
		||||
            property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP'
 | 
			
		||||
            property 'forge.logging.console.level', 'debug'
 | 
			
		||||
 | 
			
		||||
            args '--mod', 'computercraft', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
 | 
			
		||||
            mods {
 | 
			
		||||
                computercraft {
 | 
			
		||||
                    source sourceSets.main
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    mappings channel: 'snapshot', version: "${mappings_version}".toString()
 | 
			
		||||
 | 
			
		||||
    accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sourceSets {
 | 
			
		||||
    main.resources {
 | 
			
		||||
        srcDir 'src/generated/resources'
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
repositories {
 | 
			
		||||
    mavenCentral()
 | 
			
		||||
    maven {
 | 
			
		||||
        name = "JEI"
 | 
			
		||||
        url  = "http://dvs1.progwml6.com/files/maven"
 | 
			
		||||
    }
 | 
			
		||||
    maven {
 | 
			
		||||
        name = "squiddev"
 | 
			
		||||
        url = "https://dl.bintray.com/squiddev/maven"
 | 
			
		||||
        name "SquidDev"
 | 
			
		||||
        url "https://squiddev.cc/maven"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -56,77 +98,323 @@ configurations {
 | 
			
		||||
    shade
 | 
			
		||||
    compile.extendsFrom shade
 | 
			
		||||
    deployerJars
 | 
			
		||||
    cctJavadoc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    deobfProvided "mezz.jei:jei_1.12.2:4.8.5.159:api"
 | 
			
		||||
    runtime "mezz.jei:jei_1.12.2:4.8.5.159"
 | 
			
		||||
    shade 'org.squiddev:Cobalt:0.3.1'
 | 
			
		||||
    checkstyle "com.puppycrawl.tools:checkstyle:8.25"
 | 
			
		||||
 | 
			
		||||
    testCompile 'junit:junit:4.11'
 | 
			
		||||
    minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
 | 
			
		||||
 | 
			
		||||
    compileOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.3:api")
 | 
			
		||||
    compileOnly fg.deobf("com.blamejared.crafttweaker:CraftTweaker-1.15.2:6.0.0.9")
 | 
			
		||||
 | 
			
		||||
    // runtimeOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.3")
 | 
			
		||||
 | 
			
		||||
    compileOnly 'com.google.auto.service:auto-service:1.0-rc7'
 | 
			
		||||
    annotationProcessor 'com.google.auto.service:auto-service:1.0-rc7'
 | 
			
		||||
 | 
			
		||||
    shade 'org.squiddev:Cobalt:0.5.1-SNAPSHOT'
 | 
			
		||||
 | 
			
		||||
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.2'
 | 
			
		||||
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.2'
 | 
			
		||||
    testImplementation 'org.hamcrest:hamcrest:2.2'
 | 
			
		||||
 | 
			
		||||
    deployerJars "org.apache.maven.wagon:wagon-ssh:3.0.0"
 | 
			
		||||
 | 
			
		||||
    cctJavadoc 'cc.tweaked:cct-javadoc:1.1.0'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Compile tasks
 | 
			
		||||
 | 
			
		||||
javadoc {
 | 
			
		||||
    include "dan200/computercraft/api/**/*.java"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
task luaJavadoc(type: Javadoc) {
 | 
			
		||||
    description "Generates documentation for Java-side Lua functions."
 | 
			
		||||
    group "documentation"
 | 
			
		||||
 | 
			
		||||
    source = sourceSets.main.allJava
 | 
			
		||||
    destinationDir = file("doc/javadoc")
 | 
			
		||||
    classpath = sourceSets.main.compileClasspath
 | 
			
		||||
 | 
			
		||||
    options.docletpath = configurations.cctJavadoc.files as List
 | 
			
		||||
    options.doclet = "cc.tweaked.javadoc.LuaDoclet"
 | 
			
		||||
 | 
			
		||||
    // Attempt to run under Java 11 (any Java >= 9 will work though).
 | 
			
		||||
    if(System.getProperty("java.version").startsWith("1.")
 | 
			
		||||
        && (System.getenv("JAVA_HOME_11_X64") != null || project.hasProperty("java11Home"))) {
 | 
			
		||||
        executable = "${System.getenv("JAVA_HOME_11_X64") ?: project.property("java11Home")}/bin/javadoc"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
jar {
 | 
			
		||||
    dependsOn javadoc
 | 
			
		||||
 | 
			
		||||
    manifest {
 | 
			
		||||
        attributes('FMLAT': 'computercraft_at.cfg')
 | 
			
		||||
        attributes(["Specification-Title": "computercraft",
 | 
			
		||||
                    "Specification-Vendor": "SquidDev",
 | 
			
		||||
                    "Specification-Version": "1",
 | 
			
		||||
                    "Implementation-Title": "CC: Tweaked",
 | 
			
		||||
                    "Implementation-Version": "${mod_version}",
 | 
			
		||||
                    "Implementation-Vendor" :"SquidDev",
 | 
			
		||||
                    "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")])
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    into("docs", { from (javadoc.destinationDir) })
 | 
			
		||||
 | 
			
		||||
    into("api", { from (sourceSets.main.allSource) {
 | 
			
		||||
    from (sourceSets.main.allSource) {
 | 
			
		||||
        include "dan200/computercraft/api/**/*.java"
 | 
			
		||||
    }})
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
import org.ajoberstar.grgit.Grgit
 | 
			
		||||
 | 
			
		||||
processResources {
 | 
			
		||||
    inputs.property "version", project.version
 | 
			
		||||
    inputs.property "mcversion", project.minecraft.version
 | 
			
		||||
 | 
			
		||||
    def grgit = Grgit.open(dir: '.')
 | 
			
		||||
    inputs.property "commithash", grgit.head().id
 | 
			
		||||
 | 
			
		||||
    def blacklist = ['GitHub', 'dan200', 'Daniel Ratcliffe']
 | 
			
		||||
    Set<String> contributors = []
 | 
			
		||||
 | 
			
		||||
    grgit.log().each {
 | 
			
		||||
        if (!blacklist.contains(it.author.name)) contributors.add(it.author.name)
 | 
			
		||||
        if (!blacklist.contains(it.committer.name)) contributors.add(it.committer.name)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    from(sourceSets.main.resources.srcDirs) {
 | 
			
		||||
        include 'mcmod.info'
 | 
			
		||||
        include 'assets/computercraft/lua/rom/help/credits.txt'
 | 
			
		||||
 | 
			
		||||
        expand 'version':project.version,
 | 
			
		||||
               'mcversion':project.minecraft.version,
 | 
			
		||||
               'gitcontributors':contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    from(sourceSets.main.resources.srcDirs) {
 | 
			
		||||
        exclude 'mcmod.info'
 | 
			
		||||
        exclude 'assets/computercraft/lua/rom/help/credits.txt'
 | 
			
		||||
[compileJava, compileTestJava].forEach {
 | 
			
		||||
    it.configure {
 | 
			
		||||
        options.compilerArgs << "-Xlint" << "-Xlint:-processing"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
import java.nio.charset.StandardCharsets
 | 
			
		||||
import java.nio.file.*
 | 
			
		||||
import java.util.zip.*
 | 
			
		||||
 | 
			
		||||
import com.google.gson.GsonBuilder
 | 
			
		||||
import com.google.gson.JsonElement
 | 
			
		||||
import com.hierynomus.gradle.license.tasks.LicenseCheck
 | 
			
		||||
import com.hierynomus.gradle.license.tasks.LicenseFormat
 | 
			
		||||
import org.ajoberstar.grgit.Grgit
 | 
			
		||||
import proguard.gradle.ProGuardTask
 | 
			
		||||
 | 
			
		||||
task proguard(type: ProGuardTask, dependsOn: jar) {
 | 
			
		||||
    description "Removes unused shadowed classes from the jar"
 | 
			
		||||
    group "compact"
 | 
			
		||||
 | 
			
		||||
    injars jar.archivePath
 | 
			
		||||
    outjars "${jar.archivePath.absolutePath.replace(".jar", "")}-min.jar"
 | 
			
		||||
 | 
			
		||||
    // Add the main runtime jar and all non-shadowed dependencies
 | 
			
		||||
    libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
 | 
			
		||||
    libraryjars "${System.getProperty('java.home')}/lib/jce.jar"
 | 
			
		||||
    doFirst {
 | 
			
		||||
        sourceSets.main.compileClasspath
 | 
			
		||||
            .filter { !it.name.contains("Cobalt") }
 | 
			
		||||
            .each { libraryjars it }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // We want to avoid as much obfuscation as possible. We're only doing this to shrink code size.
 | 
			
		||||
    dontobfuscate; dontoptimize; keepattributes; keepparameternames
 | 
			
		||||
 | 
			
		||||
    // Proguard will remove directories by default, but that breaks JarMount.
 | 
			
		||||
    keepdirectories 'data/computercraft/lua**'
 | 
			
		||||
 | 
			
		||||
    // Preserve ComputerCraft classes - we only want to strip shadowed files.
 | 
			
		||||
    keep 'class dan200.computercraft.** { *; }'
 | 
			
		||||
 | 
			
		||||
    // LWJGL and Apache bundle Java 9 versions, which is great, but rather breaks Proguard
 | 
			
		||||
    dontwarn 'module-info'
 | 
			
		||||
    dontwarn 'org.apache.**,org.lwjgl.**'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
task proguardMove(dependsOn: proguard) {
 | 
			
		||||
    description "Replace the original jar with the minified version"
 | 
			
		||||
    group "compact"
 | 
			
		||||
 | 
			
		||||
    doLast {
 | 
			
		||||
        Files.move(
 | 
			
		||||
            file("${jar.archivePath.absolutePath.replace(".jar", "")}-min.jar").toPath(),
 | 
			
		||||
            file(jar.archivePath).toPath(),
 | 
			
		||||
            StandardCopyOption.REPLACE_EXISTING
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
processResources {
 | 
			
		||||
    inputs.property "version", mod_version
 | 
			
		||||
    inputs.property "mcversion", mc_version
 | 
			
		||||
 | 
			
		||||
    def hash = 'none'
 | 
			
		||||
    Set<String> contributors = []
 | 
			
		||||
    try {
 | 
			
		||||
        def grgit = Grgit.open(dir: '.')
 | 
			
		||||
        hash = grgit.head().id
 | 
			
		||||
 | 
			
		||||
        def blacklist = ['GitHub', 'dan200', 'Daniel Ratcliffe']
 | 
			
		||||
        grgit.log().each {
 | 
			
		||||
            if (!blacklist.contains(it.author.name)) contributors.add(it.author.name)
 | 
			
		||||
            if (!blacklist.contains(it.committer.name)) contributors.add(it.committer.name)
 | 
			
		||||
        }
 | 
			
		||||
    } catch(Exception ignored) { }
 | 
			
		||||
 | 
			
		||||
    inputs.property "commithash", hash
 | 
			
		||||
 | 
			
		||||
    from(sourceSets.main.resources.srcDirs) {
 | 
			
		||||
        include 'META-INF/mods.toml'
 | 
			
		||||
        include 'data/computercraft/lua/rom/help/credits.txt'
 | 
			
		||||
 | 
			
		||||
        expand 'version': mod_version,
 | 
			
		||||
               'mcversion': mc_version,
 | 
			
		||||
               'gitcontributors': contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    from(sourceSets.main.resources.srcDirs) {
 | 
			
		||||
        exclude 'META-INF/mods.toml'
 | 
			
		||||
        exclude 'data/computercraft/lua/rom/help/credits.txt'
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
task compressJson(dependsOn: jar) {
 | 
			
		||||
    group "compact"
 | 
			
		||||
    description "Minifies all JSON files, stripping whitespace"
 | 
			
		||||
 | 
			
		||||
    def jarPath = file(jar.archivePath)
 | 
			
		||||
 | 
			
		||||
    def tempPath = File.createTempFile("input", ".jar", temporaryDir)
 | 
			
		||||
    tempPath.deleteOnExit()
 | 
			
		||||
 | 
			
		||||
    def gson = new GsonBuilder().create()
 | 
			
		||||
 | 
			
		||||
    doLast {
 | 
			
		||||
        // Copy over all files in the current jar to the new one, running json files from GSON. As pretty printing
 | 
			
		||||
        // is turned off, they should be minified.
 | 
			
		||||
        new ZipFile(jarPath).withCloseable { inJar ->
 | 
			
		||||
            tempPath.getParentFile().mkdirs()
 | 
			
		||||
            new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(tempPath))).withCloseable { outJar ->
 | 
			
		||||
                inJar.entries().each { entry ->
 | 
			
		||||
                    if(entry.directory) {
 | 
			
		||||
                        outJar.putNextEntry(entry)
 | 
			
		||||
                    } else if(!entry.name.endsWith(".json")) {
 | 
			
		||||
                        outJar.putNextEntry(entry)
 | 
			
		||||
                        inJar.getInputStream(entry).withCloseable { outJar << it }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        ZipEntry newEntry = new ZipEntry(entry.name)
 | 
			
		||||
                        newEntry.setTime(entry.time)
 | 
			
		||||
                        outJar.putNextEntry(newEntry)
 | 
			
		||||
 | 
			
		||||
                        def element = inJar.getInputStream(entry).withCloseable { gson.fromJson(it.newReader("UTF8"), JsonElement.class) }
 | 
			
		||||
                        outJar.write(gson.toJson(element).getBytes(StandardCharsets.UTF_8))
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // And replace the original jar again
 | 
			
		||||
        Files.move(tempPath.toPath(), jarPath.toPath(), StandardCopyOption.REPLACE_EXISTING)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
assemble.dependsOn compressJson
 | 
			
		||||
 | 
			
		||||
// Check tasks
 | 
			
		||||
 | 
			
		||||
test {
 | 
			
		||||
    useJUnitPlatform()
 | 
			
		||||
    testLogging {
 | 
			
		||||
        events "skipped", "failed"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
jacocoTestReport {
 | 
			
		||||
    reports {
 | 
			
		||||
        xml.enabled true
 | 
			
		||||
        html.enabled true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
check.dependsOn jacocoTestReport
 | 
			
		||||
 | 
			
		||||
license {
 | 
			
		||||
    mapping("java", "SLASHSTAR_STYLE")
 | 
			
		||||
    strictCheck true
 | 
			
		||||
 | 
			
		||||
    ext.year = Calendar.getInstance().get(Calendar.YEAR)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
[licenseMain, licenseFormatMain].forEach {
 | 
			
		||||
    it.configure {
 | 
			
		||||
        include("**/*.java")
 | 
			
		||||
        exclude("dan200/computercraft/api/**")
 | 
			
		||||
        header rootProject.file('config/license/main.txt')
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
[licenseTest, licenseFormatTest].forEach {
 | 
			
		||||
    it.configure {
 | 
			
		||||
        include("**/*.java")
 | 
			
		||||
        header rootProject.file('config/license/main.txt')
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gradle.projectsEvaluated {
 | 
			
		||||
    tasks.withType(LicenseFormat) {
 | 
			
		||||
        outputs.upToDateWhen { false }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
task licenseAPI(type: LicenseCheck);
 | 
			
		||||
task licenseFormatAPI(type: LicenseFormat);
 | 
			
		||||
[licenseAPI, licenseFormatAPI].forEach {
 | 
			
		||||
    it.configure {
 | 
			
		||||
        source = sourceSets.main.java
 | 
			
		||||
        include("dan200/computercraft/api/**")
 | 
			
		||||
        header rootProject.file('config/license/api.txt')
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Upload tasks
 | 
			
		||||
 | 
			
		||||
task checkRelease {
 | 
			
		||||
    group "upload"
 | 
			
		||||
    description "Verifies that everything is ready for a release"
 | 
			
		||||
 | 
			
		||||
    inputs.property "version", mod_version
 | 
			
		||||
    inputs.file("src/main/resources/data/computercraft/lua/rom/help/changelog.txt")
 | 
			
		||||
    inputs.file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt")
 | 
			
		||||
 | 
			
		||||
    doLast {
 | 
			
		||||
        def ok = true
 | 
			
		||||
 | 
			
		||||
        // Check we're targetting the current version
 | 
			
		||||
        def whatsnew = new File("src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt").readLines()
 | 
			
		||||
        if (whatsnew[0] != "New features in CC: Tweaked $mod_version") {
 | 
			
		||||
            ok = false
 | 
			
		||||
            project.logger.error("Expected `whatsnew.txt' to target $mod_version.")
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check "read more" exists and trim it
 | 
			
		||||
        def idx = whatsnew.findIndexOf { it == 'Type "help changelog" to see the full version history.' }
 | 
			
		||||
        if (idx == -1) {
 | 
			
		||||
            ok = false
 | 
			
		||||
            project.logger.error("Must mention the changelog in whatsnew.txt")
 | 
			
		||||
        } else {
 | 
			
		||||
            whatsnew = whatsnew.getAt(0 ..< idx)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check whatsnew and changelog match.
 | 
			
		||||
        def versionChangelog = "# " + whatsnew.join("\n")
 | 
			
		||||
        def changelog = new File("src/main/resources/data/computercraft/lua/rom/help/changelog.txt").getText()
 | 
			
		||||
        if (!changelog.startsWith(versionChangelog)) {
 | 
			
		||||
            ok = false
 | 
			
		||||
            project.logger.error("whatsnew and changelog are not in sync")
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!ok) throw new IllegalStateException("Could not check release")
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
check.dependsOn checkRelease
 | 
			
		||||
 | 
			
		||||
curseforge {
 | 
			
		||||
    apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
 | 
			
		||||
    project {
 | 
			
		||||
        id = '282001'
 | 
			
		||||
        releaseType = 'beta'
 | 
			
		||||
        changelog = ''
 | 
			
		||||
        releaseType = 'alpha'
 | 
			
		||||
        changelog = "Release notes can be found on the GitHub repository (https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
 | 
			
		||||
 | 
			
		||||
        relations {
 | 
			
		||||
            incompatible "computercraft"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -134,7 +422,7 @@ publishing {
 | 
			
		||||
    publications {
 | 
			
		||||
        mavenJava(MavenPublication) {
 | 
			
		||||
            from components.java
 | 
			
		||||
            artifact sourceJar
 | 
			
		||||
            // artifact sourceJar
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -154,22 +442,22 @@ uploadArchives {
 | 
			
		||||
                pom.project {
 | 
			
		||||
                    name 'CC: Tweaked'
 | 
			
		||||
                    packaging 'jar'
 | 
			
		||||
                    description 'A fork of ComputerCraft which aims to provide earlier access to the more experimental and in-development features of the mod.'
 | 
			
		||||
                    description 'CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles and more to Minecraft.'
 | 
			
		||||
                    url 'https://github.com/SquidDev-CC/CC-Tweaked'
 | 
			
		||||
 | 
			
		||||
                    scm {
 | 
			
		||||
                        url 'https://github.com/dan200/ComputerCraft.git'
 | 
			
		||||
                        url 'https://github.com/SquidDev-CC/CC-Tweaked.git'
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    issueManagement {
 | 
			
		||||
                        system 'github'
 | 
			
		||||
                        url 'https://github.com/dan200/ComputerCraft/issues'
 | 
			
		||||
                        url 'https://github.com/SquidDev-CC/CC-Tweaked/issues'
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    licenses {
 | 
			
		||||
                        license {
 | 
			
		||||
                            name 'ComputerCraft Public License, Version 1.0'
 | 
			
		||||
                            url 'https://github.com/dan200/ComputerCraft/blob/master/LICENSE'
 | 
			
		||||
                            url 'https://github.com/SquidDev-CC/CC-Tweaked/blob/master/LICENSE'
 | 
			
		||||
                            distribution 'repo'
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
@@ -183,11 +471,29 @@ uploadArchives {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gradle.projectsEvaluated {
 | 
			
		||||
    tasks.withType(JavaCompile) {
 | 
			
		||||
        options.compilerArgs << "-Xlint"
 | 
			
		||||
githubRelease {
 | 
			
		||||
    token project.hasProperty('githubApiKey') ? project.githubApiKey : ''
 | 
			
		||||
    owner 'SquidDev-CC'
 | 
			
		||||
    repo 'CC-Tweaked'
 | 
			
		||||
    try {
 | 
			
		||||
        targetCommitish = Grgit.open(dir: '.').branch.current().name
 | 
			
		||||
    } catch(Exception ignored) { }
 | 
			
		||||
 | 
			
		||||
    tagName "v${mc_version}-${mod_version}"
 | 
			
		||||
    releaseName "[${mc_version}] ${mod_version}"
 | 
			
		||||
    body {
 | 
			
		||||
        "## " + new File("src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt")
 | 
			
		||||
            .readLines()
 | 
			
		||||
            .takeWhile { it != 'Type "help changelog" to see the full version history.' }
 | 
			
		||||
            .join("\n").trim()
 | 
			
		||||
    }
 | 
			
		||||
    prerelease true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
runClient.outputs.upToDateWhen { false }
 | 
			
		||||
runServer.outputs.upToDateWhen { false }
 | 
			
		||||
def uploadTasks = ["uploadArchives", "curseforge", "githubRelease"]
 | 
			
		||||
uploadTasks.forEach { tasks.getByName(it).dependsOn checkRelease }
 | 
			
		||||
 | 
			
		||||
task uploadAll(dependsOn: uploadTasks) {
 | 
			
		||||
    group "upload"
 | 
			
		||||
    description "Uploads to all repositories (Maven, Curse, GitHub release)"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
cd luaj-2.0.3
 | 
			
		||||
echo "Building LuaJ..."
 | 
			
		||||
ant clean
 | 
			
		||||
ant
 | 
			
		||||
 | 
			
		||||
echo "Copying output to libs..."
 | 
			
		||||
rm ../libs/luaj-jse-2.0.3.jar
 | 
			
		||||
cp luaj-jse-2.0.3.jar ../libs
 | 
			
		||||
 | 
			
		||||
echo "Done."
 | 
			
		||||
cd ..
 | 
			
		||||
							
								
								
									
										10
									
								
								codesize.sh
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								codesize.sh
									
									
									
									
									
								
							@@ -1,10 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
echo "Java code:"
 | 
			
		||||
cat `find src | grep \\.java$` | wc
 | 
			
		||||
 | 
			
		||||
echo "Lua code:"
 | 
			
		||||
cat `find src/main/resources/assets/computercraft/lua | grep \\.lua$` | wc
 | 
			
		||||
 | 
			
		||||
echo "JSON:"
 | 
			
		||||
cat `find src/main/resources/assets/computercraft | grep \\.json$` | wc
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										173
									
								
								config/checkstyle/checkstyle.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								config/checkstyle/checkstyle.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,173 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE module PUBLIC
 | 
			
		||||
    "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
 | 
			
		||||
    "https://checkstyle.org/dtds/configuration_1_3.dtd">
 | 
			
		||||
<module name="Checker">
 | 
			
		||||
    <property name="tabWidth" value="4"/>
 | 
			
		||||
    <property name="charset" value="UTF-8" />
 | 
			
		||||
 | 
			
		||||
    <module name="SuppressionFilter">
 | 
			
		||||
        <property name="file" value="config/checkstyle/suppressions.xml" />
 | 
			
		||||
    </module>
 | 
			
		||||
 | 
			
		||||
    <module name="BeforeExecutionExclusionFileFilter">
 | 
			
		||||
        <property name="fileNamePattern" value="render_old"/>
 | 
			
		||||
    </module>
 | 
			
		||||
 | 
			
		||||
    <module name="TreeWalker">
 | 
			
		||||
        <!-- Annotations -->
 | 
			
		||||
        <module name="AnnotationLocation" />
 | 
			
		||||
        <module name="AnnotationUseStyle" />
 | 
			
		||||
        <module name="MissingDeprecated" />
 | 
			
		||||
        <module name="MissingOverride" />
 | 
			
		||||
 | 
			
		||||
        <!-- Blocks -->
 | 
			
		||||
        <module name="EmptyBlock" />
 | 
			
		||||
        <module name="EmptyCatchBlock">
 | 
			
		||||
            <property name="exceptionVariableName" value="ignored" />
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="LeftCurly">
 | 
			
		||||
            <property name="option" value="nl" />
 | 
			
		||||
            <!-- The defaults, minus lambdas. -->
 | 
			
		||||
            <property name="tokens" value="ANNOTATION_DEF,CLASS_DEF,CTOR_DEF,ENUM_CONSTANT_DEF,ENUM_DEF,INTERFACE_DEF,LITERAL_CASE,LITERAL_CATCH,LITERAL_DEFAULT,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,METHOD_DEF,OBJBLOCK,STATIC_INIT" />
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="NeedBraces">
 | 
			
		||||
            <property name="allowSingleLineStatement" value="true"/>
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="RightCurly">
 | 
			
		||||
            <property name="option" value="alone" />
 | 
			
		||||
        </module>
 | 
			
		||||
 | 
			
		||||
        <!-- Class design. As if we've ever followed good practice here. -->
 | 
			
		||||
        <module name="FinalClass" />
 | 
			
		||||
        <module name="InterfaceIsType" />
 | 
			
		||||
        <module name="MutableException" />
 | 
			
		||||
        <module name="OneTopLevelClass" />
 | 
			
		||||
 | 
			
		||||
        <!-- Coding -->
 | 
			
		||||
        <module name="ArrayTrailingComma" />
 | 
			
		||||
        <module name="EqualsHashCode" />
 | 
			
		||||
        <!-- FallThrough does not handle unreachable code well -->
 | 
			
		||||
        <module name="IllegalInstantiation" />
 | 
			
		||||
        <module name="IllegalThrows" />
 | 
			
		||||
        <module name="ModifiedControlVariable" />
 | 
			
		||||
        <module name="NoClone" />
 | 
			
		||||
        <module name="NoFinalizer" />
 | 
			
		||||
        <module name="OneStatementPerLine" />
 | 
			
		||||
        <module name="PackageDeclaration" />
 | 
			
		||||
        <module name="SimplifyBooleanExpression" />
 | 
			
		||||
        <module name="SimplifyBooleanReturn" />
 | 
			
		||||
        <module name="StringLiteralEquality" />
 | 
			
		||||
        <module name="UnnecessaryParentheses" />
 | 
			
		||||
        <module name="UnnecessarySemicolonAfterTypeMemberDeclaration" />
 | 
			
		||||
        <module name="UnnecessarySemicolonInTryWithResources" />
 | 
			
		||||
        <module name="UnnecessarySemicolonInEnumeration" />
 | 
			
		||||
 | 
			
		||||
        <!-- Imports -->
 | 
			
		||||
        <module name="CustomImportOrder" />
 | 
			
		||||
        <module name="IllegalImport" />
 | 
			
		||||
        <module name="RedundantImport" />
 | 
			
		||||
        <module name="UnusedImports" />
 | 
			
		||||
 | 
			
		||||
        <!-- Javadoc -->
 | 
			
		||||
        <!-- TODO: Missing* checks for the dan200.computercraft.api package? -->
 | 
			
		||||
        <module name="AtclauseOrder" />
 | 
			
		||||
        <module name="InvalidJavadocPosition" />
 | 
			
		||||
        <module name="JavadocBlockTagLocation" />
 | 
			
		||||
        <module name="JavadocMethod"/>
 | 
			
		||||
        <module name="JavadocType"/>
 | 
			
		||||
        <module name="JavadocStyle" />
 | 
			
		||||
        <module name="NonEmptyAtclauseDescription" />
 | 
			
		||||
        <module name="SingleLineJavadoc" />
 | 
			
		||||
        <module name="SummaryJavadocCheck"/>
 | 
			
		||||
 | 
			
		||||
        <!-- Misc -->
 | 
			
		||||
        <module name="ArrayTypeStyle" />
 | 
			
		||||
        <module name="CommentsIndentation" />
 | 
			
		||||
        <module name="Indentation" />
 | 
			
		||||
        <module name="OuterTypeFilename" />
 | 
			
		||||
 | 
			
		||||
        <!-- Modifiers -->
 | 
			
		||||
        <module name="ModifierOrder" />
 | 
			
		||||
        <module name="RedundantModifier" />
 | 
			
		||||
 | 
			
		||||
        <!-- Naming -->
 | 
			
		||||
        <module name="ClassTypeParameterName" />
 | 
			
		||||
        <module name="InterfaceTypeParameterName" />
 | 
			
		||||
        <module name="LambdaParameterName" />
 | 
			
		||||
        <module name="LocalFinalVariableName" />
 | 
			
		||||
        <module name="LocalVariableName" />
 | 
			
		||||
        <!-- Allow an optional m_ on private members -->
 | 
			
		||||
        <module name="MemberName">
 | 
			
		||||
            <property name="applyToPrivate" value="false" />
 | 
			
		||||
            <property name="applyToPackage" value="false" />
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="MemberName">
 | 
			
		||||
            <property name="format" value="^(m_)?[a-z][a-zA-Z0-9]*$" />
 | 
			
		||||
            <property name="applyToPrivate" value="true" />
 | 
			
		||||
            <property name="applyToPackage" value="true" />
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="MethodName" />
 | 
			
		||||
        <module name="MethodTypeParameterName" />
 | 
			
		||||
        <module name="PackageName">
 | 
			
		||||
            <property name="format" value="^dan200\.computercraf(\.[a-z][a-z0-9]*)*" />
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="ParameterName" />
 | 
			
		||||
        <module name="StaticVariableName">
 | 
			
		||||
            <property name="format" value="^[a-z][a-zA-Z0-9]*|CAPABILITY(_[A-Z_]+)?$" />
 | 
			
		||||
            <property name="applyToPrivate" value="false" />
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="StaticVariableName">
 | 
			
		||||
            <property name="format" value="^(s_)?[a-z][a-zA-Z0-9]*|CAPABILITY(_[A-Z_]+)?$" />
 | 
			
		||||
            <property name="applyToPrivate" value="true" />
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="TypeName" />
 | 
			
		||||
 | 
			
		||||
        <!-- Whitespace -->
 | 
			
		||||
        <module name="EmptyForInitializerPad"/>
 | 
			
		||||
        <module name="EmptyForIteratorPad">
 | 
			
		||||
            <property name="option" value="space"/>
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="GenericWhitespace" />
 | 
			
		||||
        <module name="MethodParamPad" />
 | 
			
		||||
        <module name="NoLineWrap" />
 | 
			
		||||
        <module name="NoWhitespaceAfter">
 | 
			
		||||
            <property name="tokens" value="AT,INC,DEC,UNARY_MINUS,UNARY_PLUS,BNOT,LNOT,DOT,ARRAY_DECLARATOR,INDEX_OP" />
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="NoWhitespaceBefore" />
 | 
			
		||||
        <!-- TODO: Decide on an OperatorWrap style. -->
 | 
			
		||||
        <module name="ParenPad">
 | 
			
		||||
            <property name="option" value="space" />
 | 
			
		||||
            <property name="tokens" value="ANNOTATION,ANNOTATION_FIELD_DEF,CTOR_CALL,CTOR_DEF,ENUM_CONSTANT_DEF,LITERAL_CATCH,LITERAL_DO,LITERAL_FOR,LITERAL_IF,LITERAL_NEW,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_WHILE,METHOD_CALL,METHOD_DEF,RESOURCE_SPECIFICATION,SUPER_CTOR_CALL,LAMBDA" />
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="ParenPad">
 | 
			
		||||
            <property name="option" value="nospace" />
 | 
			
		||||
            <property name="tokens" value="DOT,EXPR,QUESTION" />
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="SeparatorWrap">
 | 
			
		||||
            <property name="option" value="eol" />
 | 
			
		||||
            <property name="tokens" value="COMMA,SEMI,ELLIPSIS,ARRAY_DECLARATOR,RBRACK,METHOD_REF" />
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="SeparatorWrap">
 | 
			
		||||
            <property name="option" value="nl" />
 | 
			
		||||
            <property name="tokens" value="DOT,AT" />
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="SingleSpaceSeparator" />
 | 
			
		||||
        <module name="TypecastParenPad" />
 | 
			
		||||
        <module name="WhitespaceAfter">
 | 
			
		||||
            <property name="tokens" value="COMMA" />
 | 
			
		||||
        </module>
 | 
			
		||||
        <module name="WhitespaceAround">
 | 
			
		||||
            <property name="allowEmptyConstructors" value="true" />
 | 
			
		||||
            <property name="ignoreEnhancedForColon" value="false" />
 | 
			
		||||
            <property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,EQUAL,GE,GT,LAMBDA,LAND,LCURLY,LE,LITERAL_RETURN,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,RCURLY,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND" />
 | 
			
		||||
        </module>
 | 
			
		||||
    </module>
 | 
			
		||||
 | 
			
		||||
    <module name="FileTabCharacter" />
 | 
			
		||||
    <module name="NewlineAtEndOfFile" />
 | 
			
		||||
    <module name="RegexpSingleline">
 | 
			
		||||
        <property name="format" value="\s+$"/>
 | 
			
		||||
        <property name="message" value="Trailing whitespace"/>
 | 
			
		||||
    </module>
 | 
			
		||||
</module>
 | 
			
		||||
							
								
								
									
										15
									
								
								config/checkstyle/suppressions.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								config/checkstyle/suppressions.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE suppressions PUBLIC
 | 
			
		||||
    "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
 | 
			
		||||
    "https://checkstyle.org/dtds/suppressions_1_2.dtd">
 | 
			
		||||
<suppressions>
 | 
			
		||||
    <!-- All the config options and method fields. -->
 | 
			
		||||
    <suppress checks="StaticVariableName" files=".*[\\/]ComputerCraft.java" />
 | 
			
		||||
    <suppress checks="StaticVariableName" files=".*[\\/]ComputerCraftAPI.java" />
 | 
			
		||||
 | 
			
		||||
    <!-- Do not check for missing package Javadoc. -->
 | 
			
		||||
    <suppress checks="JavadocStyle" files=".*[\\/]package-info.java" />
 | 
			
		||||
 | 
			
		||||
    <!-- The commands API is documented in Lua. -->
 | 
			
		||||
    <suppress checks="SummaryJavadocCheck" files=".*[\\/]CommandAPI.java" />
 | 
			
		||||
</suppressions>
 | 
			
		||||
							
								
								
									
										2491
									
								
								config/idea/codeInspectionSettings.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2491
									
								
								config/idea/codeInspectionSettings.xml
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										61
									
								
								config/idea/codeStyleSettings.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								config/idea/codeStyleSettings.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
<code_scheme name="Project" version="173">
 | 
			
		||||
  <JSON>
 | 
			
		||||
    <option name="OBJECT_WRAPPING" value="1" />
 | 
			
		||||
    <option name="ARRAY_WRAPPING" value="1" />
 | 
			
		||||
  </JSON>
 | 
			
		||||
  <JavaCodeStyleSettings>
 | 
			
		||||
    <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
 | 
			
		||||
      <value />
 | 
			
		||||
    </option>
 | 
			
		||||
    <option name="JD_P_AT_EMPTY_LINES" value="false" />
 | 
			
		||||
    <option name="JD_PRESERVE_LINE_FEEDS" value="true" />
 | 
			
		||||
  </JavaCodeStyleSettings>
 | 
			
		||||
  <codeStyleSettings language="JAVA">
 | 
			
		||||
    <option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
 | 
			
		||||
    <option name="BRACE_STYLE" value="2" />
 | 
			
		||||
    <option name="CLASS_BRACE_STYLE" value="2" />
 | 
			
		||||
    <option name="METHOD_BRACE_STYLE" value="2" />
 | 
			
		||||
    <option name="LAMBDA_BRACE_STYLE" value="5" />
 | 
			
		||||
    <option name="ELSE_ON_NEW_LINE" value="true" />
 | 
			
		||||
    <option name="CATCH_ON_NEW_LINE" value="true" />
 | 
			
		||||
    <option name="FINALLY_ON_NEW_LINE" value="true" />
 | 
			
		||||
    <option name="SPACE_WITHIN_METHOD_CALL_PARENTHESES" value="true" />
 | 
			
		||||
    <option name="SPACE_WITHIN_METHOD_PARENTHESES" value="true" />
 | 
			
		||||
    <option name="SPACE_WITHIN_IF_PARENTHESES" value="true" />
 | 
			
		||||
    <option name="SPACE_WITHIN_WHILE_PARENTHESES" value="true" />
 | 
			
		||||
    <option name="SPACE_WITHIN_FOR_PARENTHESES" value="true" />
 | 
			
		||||
    <option name="SPACE_WITHIN_TRY_PARENTHESES" value="true" />
 | 
			
		||||
    <option name="SPACE_WITHIN_CATCH_PARENTHESES" value="true" />
 | 
			
		||||
    <option name="SPACE_WITHIN_SWITCH_PARENTHESES" value="true" />
 | 
			
		||||
    <option name="SPACE_WITHIN_SYNCHRONIZED_PARENTHESES" value="true" />
 | 
			
		||||
    <option name="SPACE_WITHIN_ARRAY_INITIALIZER_BRACES" value="true" />
 | 
			
		||||
    <option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
 | 
			
		||||
    <option name="SPACE_BEFORE_WHILE_PARENTHESES" value="false" />
 | 
			
		||||
    <option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
 | 
			
		||||
    <option name="SPACE_BEFORE_TRY_PARENTHESES" value="false" />
 | 
			
		||||
    <option name="SPACE_BEFORE_CATCH_PARENTHESES" value="false" />
 | 
			
		||||
    <option name="SPACE_BEFORE_SWITCH_PARENTHESES" value="false" />
 | 
			
		||||
    <option name="SPACE_BEFORE_SYNCHRONIZED_PARENTHESES" value="false" />
 | 
			
		||||
    <option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
 | 
			
		||||
    <option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
 | 
			
		||||
    <option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" />
 | 
			
		||||
    <option name="KEEP_SIMPLE_CLASSES_IN_ONE_LINE" value="true" />
 | 
			
		||||
    <option name="IF_BRACE_FORCE" value="1" />
 | 
			
		||||
    <option name="DOWHILE_BRACE_FORCE" value="1" />
 | 
			
		||||
    <option name="WHILE_BRACE_FORCE" value="1" />
 | 
			
		||||
    <option name="FOR_BRACE_FORCE" value="1" />
 | 
			
		||||
    <option name="SPACE_WITHIN_ANNOTATION_PARENTHESES" value="true" />
 | 
			
		||||
    <indentOptions>
 | 
			
		||||
      <option name="CONTINUATION_INDENT_SIZE" value="4" />
 | 
			
		||||
    </indentOptions>
 | 
			
		||||
  </codeStyleSettings>
 | 
			
		||||
  <codeStyleSettings language="JSON">
 | 
			
		||||
    <option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
 | 
			
		||||
    <option name="SPACE_WITHIN_BRACKETS" value="true" />
 | 
			
		||||
    <option name="SPACE_WITHIN_BRACES" value="true" />
 | 
			
		||||
    <indentOptions>
 | 
			
		||||
      <option name="INDENT_SIZE" value="4" />
 | 
			
		||||
      <option name="CONTINUATION_INDENT_SIZE" value="4" />
 | 
			
		||||
    </indentOptions>
 | 
			
		||||
  </codeStyleSettings>
 | 
			
		||||
</code_scheme>
 | 
			
		||||
							
								
								
									
										3
									
								
								config/license/api.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								config/license/api.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
This file is part of the public ComputerCraft API - http://www.computercraft.info
 | 
			
		||||
Copyright Daniel Ratcliffe, 2011-${year}. This API may be redistributed unmodified and in full only.
 | 
			
		||||
For help using the API, and posting your mods, visit the forums at computercraft.info.
 | 
			
		||||
							
								
								
									
										3
									
								
								config/license/main.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								config/license/main.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
This file is part of ComputerCraft - http://www.computercraft.info
 | 
			
		||||
Copyright Daniel Ratcliffe, 2011-${year}. Do not distribute without permission.
 | 
			
		||||
Send enquiries to dratcliffe@gmail.com
 | 
			
		||||
							
								
								
									
										21
									
								
								deploy.sh
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								deploy.sh
									
									
									
									
									
								
							@@ -1,21 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
echo "Building with gradle..."
 | 
			
		||||
rm -rf build/libs
 | 
			
		||||
rm -rf build/resources
 | 
			
		||||
rm -rf build/classes
 | 
			
		||||
chmod -R +rw src/main/resources
 | 
			
		||||
chmod +x gradlew
 | 
			
		||||
./gradlew build
 | 
			
		||||
 | 
			
		||||
echo "Deleting old deployment..."
 | 
			
		||||
rm -rf deploy
 | 
			
		||||
mkdir deploy
 | 
			
		||||
 | 
			
		||||
echo "Making new deployment..."
 | 
			
		||||
INPUTJAR=`ls -1 build/libs | grep -v sources`
 | 
			
		||||
OUTPUTJAR=`ls -1 build/libs | grep -v sources | sed s/\-//g`
 | 
			
		||||
FRIENDLYNAME=`ls -1 build/libs | grep -v sources | sed s/\-/\ /g | sed s/\.jar//g`
 | 
			
		||||
cp build/libs/$INPUTJAR deploy/$OUTPUTJAR
 | 
			
		||||
 | 
			
		||||
echo "Done."
 | 
			
		||||
							
								
								
									
										11
									
								
								doc/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								doc/index.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
#  [](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
 | 
			
		||||
 | 
			
		||||
CC: Tweaked is a fork of [ComputerCraft], adding programmable computers, turtles and more to Minecraft.
 | 
			
		||||
 | 
			
		||||
This website contains documentation for all Lua libraries and APIs from the latest version of CC: Tweaked. This
 | 
			
		||||
documentation is still in development, so will most likely be incomplete. If you've found something you think is wrong,
 | 
			
		||||
or would like to help out [please get in touch on GitHub][gh].
 | 
			
		||||
 | 
			
		||||
[bug]: https://github.com/SquidDev-CC/CC-Tweaked/issues/new/choose
 | 
			
		||||
[computercraft]: https://github.com/dan200/ComputerCraft "ComputerCraft on GitHub"
 | 
			
		||||
[gh]: https://github.com/SquidDev-CC/CC-Tweaked "CC:Tweaked on GitHub"
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB  | 
							
								
								
									
										34
									
								
								doc/stub/fs.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								doc/stub/fs.lua
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
---  The FS API allows you to manipulate files and the filesystem.
 | 
			
		||||
--
 | 
			
		||||
-- @module fs
 | 
			
		||||
 | 
			
		||||
--- Returns true if a path is mounted to the parent filesystem.
 | 
			
		||||
--
 | 
			
		||||
-- The root filesystem "/" is considered a mount, along with disk folders and
 | 
			
		||||
-- the rom folder. Other programs (such as network shares) can exstend this to
 | 
			
		||||
-- make other mount types by correctly assigning their return value for getDrive.
 | 
			
		||||
--
 | 
			
		||||
-- @tparam string path The path to check.
 | 
			
		||||
-- @treturn boolean If the path is mounted, rather than a normal file/folder.
 | 
			
		||||
-- @throws If the path does not exist.
 | 
			
		||||
-- @see getDrive
 | 
			
		||||
function isDriveRoot(path) end
 | 
			
		||||
 | 
			
		||||
--[[- Provides completion for a file or directory name, suitable for use with
 | 
			
		||||
@{read}.
 | 
			
		||||
 | 
			
		||||
When a directory is a possible candidate for completion, two entries are
 | 
			
		||||
included - one with a trailing slash (indicating that entries within this
 | 
			
		||||
directory exist) and one without it (meaning this entry is an immediate
 | 
			
		||||
completion candidate). `include_dirs` can be set to @{false} to only include
 | 
			
		||||
those with a trailing slash.
 | 
			
		||||
 | 
			
		||||
@tparam string path The path to complete.
 | 
			
		||||
@tparam string location The location where paths are resolved from.
 | 
			
		||||
@tparam[opt] boolean include_files When @{false}, only directories will be
 | 
			
		||||
included in the returned list.
 | 
			
		||||
@tparam[opt] boolean include_dirs When @{false}, "raw" directories will not be
 | 
			
		||||
included in the returned list.
 | 
			
		||||
@treturn { string... } A list of possible completion candidates.
 | 
			
		||||
]]
 | 
			
		||||
function complete(path, location, include_files, include_dirs) end
 | 
			
		||||
							
								
								
									
										159
									
								
								doc/stub/http.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								doc/stub/http.lua
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,159 @@
 | 
			
		||||
--- The http library allows communicating with web servers, sending and
 | 
			
		||||
-- receiving data from them.
 | 
			
		||||
--
 | 
			
		||||
-- #### `http_check` event
 | 
			
		||||
--
 | 
			
		||||
-- @module http
 | 
			
		||||
 | 
			
		||||
--- Asynchronously make a HTTP request to the given url.
 | 
			
		||||
--
 | 
			
		||||
-- This returns immediately, a [`http_success`](#http-success-event) or
 | 
			
		||||
-- [`http_failure`](#http-failure-event) will be queued once the request has
 | 
			
		||||
-- completed.
 | 
			
		||||
--
 | 
			
		||||
-- @tparam      string url   The url to request
 | 
			
		||||
-- @tparam[opt] string body  An optional string containing the body of the
 | 
			
		||||
-- request. If specified, a `POST` request will be made instead.
 | 
			
		||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
 | 
			
		||||
-- of this request.
 | 
			
		||||
-- @tparam[opt] boolean binary Whether to make a binary HTTP request. If true,
 | 
			
		||||
-- the body will not be UTF-8 encoded, and the received response will not be
 | 
			
		||||
-- decoded.
 | 
			
		||||
--
 | 
			
		||||
-- @tparam[2] {
 | 
			
		||||
--   url = string, body? = string, headers? = { [string] = string },
 | 
			
		||||
--   binary? = boolean, method? = string, redirect? = boolean,
 | 
			
		||||
-- } request Options for the request.
 | 
			
		||||
--
 | 
			
		||||
-- This table form is an expanded version of the previous syntax. All arguments
 | 
			
		||||
-- from above are passed in as fields instead (for instance,
 | 
			
		||||
-- `http.request("https://example.com")` becomes `http.request { url =
 | 
			
		||||
-- "https://example.com" }`).
 | 
			
		||||
--
 | 
			
		||||
-- This table also accepts several additional options:
 | 
			
		||||
--
 | 
			
		||||
--  - `method`: Which HTTP method to use, for instance `"PATCH"` or `"DELETE"`.
 | 
			
		||||
--  - `redirect`: Whether to follow HTTP redirects. Defaults to true.
 | 
			
		||||
--
 | 
			
		||||
-- @see http.get  For a synchronous way to make GET requests.
 | 
			
		||||
-- @see http.post For a synchronous way to make POST requests.
 | 
			
		||||
function request(...) end
 | 
			
		||||
 | 
			
		||||
--- Make a HTTP GET request to the given url.
 | 
			
		||||
--
 | 
			
		||||
-- @tparam string url   The url to request
 | 
			
		||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
 | 
			
		||||
-- of this request.
 | 
			
		||||
-- @tparam[opt] boolean binary Whether to make a binary HTTP request. If true,
 | 
			
		||||
-- the body will not be UTF-8 encoded, and the received response will not be
 | 
			
		||||
-- decoded.
 | 
			
		||||
--
 | 
			
		||||
-- @tparam[2] {
 | 
			
		||||
--   url = string, headers? = { [string] = string },
 | 
			
		||||
--   binary? = boolean, method? = string, redirect? = boolean,
 | 
			
		||||
-- } request Options for the request. See @{http.request} for details on how
 | 
			
		||||
-- these options behave.
 | 
			
		||||
--
 | 
			
		||||
-- @treturn Response The resulting http response, which can be read from.
 | 
			
		||||
-- @treturn[2] nil When the http request failed, such as in the event of a 404
 | 
			
		||||
-- error or connection timeout.
 | 
			
		||||
-- @treturn string A message detailing why the request failed.
 | 
			
		||||
-- @treturn Response|nil The failing http response, if available.
 | 
			
		||||
--
 | 
			
		||||
-- @usage Make a request to [example.computercraft.cc](https://example.computercraft.cc),
 | 
			
		||||
-- and print the returned page.
 | 
			
		||||
-- ```lua
 | 
			
		||||
-- local request = http.get("https://example.computercraft.cc")
 | 
			
		||||
-- print(request.readAll())
 | 
			
		||||
-- -- => HTTP is working!
 | 
			
		||||
-- request.close()
 | 
			
		||||
-- ```
 | 
			
		||||
function get(...) end
 | 
			
		||||
 | 
			
		||||
--- Make a HTTP POST request to the given url.
 | 
			
		||||
--
 | 
			
		||||
-- @tparam string url   The url to request
 | 
			
		||||
-- @tparam string body  The body of the POST request.
 | 
			
		||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
 | 
			
		||||
-- of this request.
 | 
			
		||||
-- @tparam[opt] boolean binary Whether to make a binary HTTP request. If true,
 | 
			
		||||
-- the body will not be UTF-8 encoded, and the received response will not be
 | 
			
		||||
-- decoded.
 | 
			
		||||
--
 | 
			
		||||
-- @tparam[2] {
 | 
			
		||||
--   url = string, body? = string, headers? = { [string] = string },
 | 
			
		||||
--   binary? = boolean, method? = string, redirect? = boolean,
 | 
			
		||||
-- } request Options for the request. See @{http.request} for details on how
 | 
			
		||||
-- these options behave.
 | 
			
		||||
--
 | 
			
		||||
-- @treturn Response The resulting http response, which can be read from.
 | 
			
		||||
-- @treturn[2] nil When the http request failed, such as in the event of a 404
 | 
			
		||||
-- error or connection timeout.
 | 
			
		||||
-- @treturn string A message detailing why the request failed.
 | 
			
		||||
-- @treturn Response|nil The failing http response, if available.
 | 
			
		||||
function post(...) end
 | 
			
		||||
 | 
			
		||||
--- Asynchronously determine whether a URL can be requested.
 | 
			
		||||
--
 | 
			
		||||
-- If this returns `true`, one should also listen for [`http_check`
 | 
			
		||||
-- events](#http-check-event) which will container further information about
 | 
			
		||||
-- whether the URL is allowed or not.
 | 
			
		||||
--
 | 
			
		||||
-- @tparam string url The URL to check.
 | 
			
		||||
-- @treturn true When this url is not invalid. This does not imply that it is
 | 
			
		||||
-- allowed - see the comment above.
 | 
			
		||||
-- @treturn[2] false When this url is invalid.
 | 
			
		||||
-- @treturn string A reason why this URL is not valid (for instance, if it is
 | 
			
		||||
-- malformed, or blocked).
 | 
			
		||||
--
 | 
			
		||||
-- @see http.checkURL For a synchronous version.
 | 
			
		||||
function checkURLAsync(url) end
 | 
			
		||||
 | 
			
		||||
--- Determine whether a URL can be requested.
 | 
			
		||||
--
 | 
			
		||||
-- If this returns `true`, one should also listen for [`http_check`
 | 
			
		||||
-- events](#http-check-event) which will container further information about
 | 
			
		||||
-- whether the URL is allowed or not.
 | 
			
		||||
--
 | 
			
		||||
-- @tparam string url The URL to check.
 | 
			
		||||
-- @treturn true When this url is valid and can be requested via @{http.request}.
 | 
			
		||||
-- @treturn[2] false When this url is invalid.
 | 
			
		||||
-- @treturn string A reason why this URL is not valid (for instance, if it is
 | 
			
		||||
-- malformed, or blocked).
 | 
			
		||||
--
 | 
			
		||||
-- @see http.checkURLAsync For an asynchronous version.
 | 
			
		||||
--
 | 
			
		||||
-- @usage
 | 
			
		||||
-- ```lua
 | 
			
		||||
-- print(http.checkURL("https://example.computercraft.cc/"))
 | 
			
		||||
-- -- => true
 | 
			
		||||
-- print(http.checkURL("http://localhost/"))
 | 
			
		||||
-- -- => false Domain not permitted
 | 
			
		||||
-- print(http.checkURL("not a url"))
 | 
			
		||||
-- -- => false URL malformed
 | 
			
		||||
-- ```
 | 
			
		||||
function checkURL(url) end
 | 
			
		||||
 | 
			
		||||
--- Open a websocket.
 | 
			
		||||
--
 | 
			
		||||
-- @tparam string url The websocket url to connect to. This should have the
 | 
			
		||||
-- `ws://` or `wss://` protocol.
 | 
			
		||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
 | 
			
		||||
-- of the initial websocket connection.
 | 
			
		||||
--
 | 
			
		||||
-- @treturn Websocket The websocket connection.
 | 
			
		||||
-- @treturn[2] false If the websocket connection failed.
 | 
			
		||||
-- @treturn string An error message describing why the connection failed.
 | 
			
		||||
function websocket(url, headers) end
 | 
			
		||||
 | 
			
		||||
--- Asynchronously open a websocket.
 | 
			
		||||
--
 | 
			
		||||
-- This returns immediately, a [`websocket_success`](#websocket-success-event)
 | 
			
		||||
-- or [`websocket_failure`](#websocket-failure-event) will be queued once the
 | 
			
		||||
-- request has completed.
 | 
			
		||||
--
 | 
			
		||||
-- @tparam string url The websocket url to connect to. This should have the
 | 
			
		||||
-- `ws://` or `wss://` protocol.
 | 
			
		||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
 | 
			
		||||
-- of the initial websocket connection.
 | 
			
		||||
function websocketAsync(url, headers) end
 | 
			
		||||
							
								
								
									
										6
									
								
								doc/stub/os.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								doc/stub/os.lua
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
-- Defined in bios.lua
 | 
			
		||||
function loadAPI(path) end
 | 
			
		||||
function pullEvent(filter) end
 | 
			
		||||
function pullEventRaw(filter) end
 | 
			
		||||
function version() end
 | 
			
		||||
function run(env, path, ...) end
 | 
			
		||||
							
								
								
									
										1
									
								
								doc/stub/turtle.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								doc/stub/turtle.lua
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
function craft(limit) end
 | 
			
		||||
							
								
								
									
										191
									
								
								doc/styles.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								doc/styles.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,191 @@
 | 
			
		||||
/* Basic reset on elements */
 | 
			
		||||
h1, h2, h3, h4, p, table, div, body {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
    border: 0;
 | 
			
		||||
    font-size: 100%;
 | 
			
		||||
    font: inherit;
 | 
			
		||||
    vertical-align: baseline;
 | 
			
		||||
}
 | 
			
		||||
/* Make the page a little more airy */
 | 
			
		||||
body {
 | 
			
		||||
    margin: 20px auto;
 | 
			
		||||
    max-width: 1200px;
 | 
			
		||||
    padding: 0 10px;
 | 
			
		||||
    line-height: 1.6;
 | 
			
		||||
    color: #222;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Try to use system default fonts. */
 | 
			
		||||
body {
 | 
			
		||||
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans",
 | 
			
		||||
                 "Droid Sans", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
code, pre, .parameter, .type, .definition-name, .reference-code {
 | 
			
		||||
    font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Some definitions of basic tags */
 | 
			
		||||
code {
 | 
			
		||||
    color: #c7254e;
 | 
			
		||||
    background-color: #f9f2f4;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
p {
 | 
			
		||||
    margin: 0.9em 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h1 {
 | 
			
		||||
    font-size: 1.5em;
 | 
			
		||||
    font-weight: lighter;
 | 
			
		||||
    border-bottom: solid 1px #aaa;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h2, h3, h4 { margin: 1.4em 0 0.3em;}
 | 
			
		||||
h2 { font-size: 1.25em; }
 | 
			
		||||
h3 { font-size: 1.15em; font-weight: bold; }
 | 
			
		||||
h4 { font-size: 1.06em; }
 | 
			
		||||
 | 
			
		||||
a, a:visited, a:active { font-weight: bold; color: #004080; text-decoration: none; }
 | 
			
		||||
a:hover { text-decoration: underline; }
 | 
			
		||||
 | 
			
		||||
blockquote {
 | 
			
		||||
    padding: 0.3em;
 | 
			
		||||
    margin: 1em 0;
 | 
			
		||||
    background: #f0f0f0;
 | 
			
		||||
    border-left: solid 0.5em #ccc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Stop sublists from having initial vertical space */
 | 
			
		||||
ul ul { margin-top: 0px; }
 | 
			
		||||
ol ul { margin-top: 0px; }
 | 
			
		||||
ol ol { margin-top: 0px; }
 | 
			
		||||
ul ol { margin-top: 0px; }
 | 
			
		||||
 | 
			
		||||
/* Make the target distinct; helps when we're navigating to a function */
 | 
			
		||||
a:target + * { background-color: #FFFF99; }
 | 
			
		||||
 | 
			
		||||
/* Allow linking to any subsection */
 | 
			
		||||
a[name]::before { content: "#"; }
 | 
			
		||||
 | 
			
		||||
/* Layout */
 | 
			
		||||
#main {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-wrap: nowrap;
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
    min-height: calc(100vh - 100px);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#main > nav {
 | 
			
		||||
    flex-basis: 30%;
 | 
			
		||||
    min-width: 150px;
 | 
			
		||||
    max-width: 250px;
 | 
			
		||||
    background-color: #f0f0f0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nav h1, nav ul { padding: 0em 10px; }
 | 
			
		||||
 | 
			
		||||
nav h2 {
 | 
			
		||||
    background-color:#e7e7e7;
 | 
			
		||||
    font-size: 1.1em;
 | 
			
		||||
    color:#000000;
 | 
			
		||||
    padding: 5px 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nav ul {
 | 
			
		||||
    list-style-type: none;
 | 
			
		||||
    margin: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#content {
 | 
			
		||||
    flex-shrink: 1;
 | 
			
		||||
    flex-basis: 80%;
 | 
			
		||||
    padding: 0px 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
footer {
 | 
			
		||||
    text-align: right;
 | 
			
		||||
    font-size: 0.8em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* The definition lists at the top of each page */
 | 
			
		||||
table.definition-list {
 | 
			
		||||
    border-collapse: collapse;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.definition-list td, table.definition-list th {
 | 
			
		||||
    border: 1px solid #cccccc;
 | 
			
		||||
    padding: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.definition-list th {
 | 
			
		||||
    background-color: #f0f0f0;
 | 
			
		||||
    min-width: 200px;
 | 
			
		||||
    white-space: nowrap;
 | 
			
		||||
    text-align: right;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table.definition-list td { width: 100%; }
 | 
			
		||||
 | 
			
		||||
dl.definition dt {
 | 
			
		||||
    border-top: 1px solid #ccc;
 | 
			
		||||
    padding-top: 1em;
 | 
			
		||||
    display: flex;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl.definition dt .definition-name {
 | 
			
		||||
    padding: 0 0.1em;
 | 
			
		||||
    margin: 0 0.1em;
 | 
			
		||||
    flex-grow: 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
dl.definition dd {
 | 
			
		||||
    padding-bottom: 1em;
 | 
			
		||||
    margin: 10px 0 0 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dl.definition h3 {
 | 
			
		||||
    font-size: .95em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Links to source-code */
 | 
			
		||||
.source-link { font-size: 0.8em; }
 | 
			
		||||
.source-link::before { content: '[' }
 | 
			
		||||
.source-link::after  { content: ']' }
 | 
			
		||||
a.source-link, a.source-link:visited, a.source-link:active { color: #505050; }
 | 
			
		||||
 | 
			
		||||
/* Method definitions */
 | 
			
		||||
span.parameter:after { content:":"; padding-left: 0.3em; }
 | 
			
		||||
.optional { text-decoration: underline dotted; }
 | 
			
		||||
 | 
			
		||||
/** Fancy colour display. */
 | 
			
		||||
.colour-ref {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    width: 0.8em;
 | 
			
		||||
    height: 0.8em;
 | 
			
		||||
    margin: 0.1em 0.1em 0.3em 0.1em; /* Terrrible hack to force vertical alignment. */
 | 
			
		||||
    border: solid 1px black;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    vertical-align: middle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* styles for prettification of source */
 | 
			
		||||
.highlight .comment { color: #558817; }
 | 
			
		||||
.highlight .constant { color: #a8660d; }
 | 
			
		||||
.highlight .escape { color: #844631; }
 | 
			
		||||
.highlight .keyword { color: #aa5050; font-weight: bold; }
 | 
			
		||||
.highlight .library { color: #0e7c6b; }
 | 
			
		||||
.highlight .marker { color: #512b1e; background: #fedc56; font-weight: bold; }
 | 
			
		||||
.highlight .string { color: #8080ff; }
 | 
			
		||||
.highlight .literal-kw { color: #8080ff; }
 | 
			
		||||
.highlight .number { color: #f8660d; }
 | 
			
		||||
.highlight .operator { color: #2239a8; font-weight: bold; }
 | 
			
		||||
.highlight .preprocessor, pre .prepro { color: #a33243; }
 | 
			
		||||
.highlight .global { color: #800080; }
 | 
			
		||||
.highlight .user-keyword { color: #800080; }
 | 
			
		||||
.highlight .prompt { color: #558817; }
 | 
			
		||||
.highlight .url { color: #272fc2; text-decoration: underline; }
 | 
			
		||||
							
								
								
									
										7
									
								
								gradle.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								gradle.properties
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
# Mod properties
 | 
			
		||||
mod_version=1.91.0
 | 
			
		||||
 | 
			
		||||
# Minecraft properties (update mods.toml when changing)
 | 
			
		||||
mc_version=1.16.2
 | 
			
		||||
forge_version=33.0.20
 | 
			
		||||
mappings_version=20200723-1.16.1
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										2
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
			
		||||
distributionBase=GRADLE_USER_HOME
 | 
			
		||||
distributionPath=wrapper/dists
 | 
			
		||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
 | 
			
		||||
zipStoreBase=GRADLE_USER_HOME
 | 
			
		||||
zipStorePath=wrapper/dists
 | 
			
		||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-bin.zip
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										110
									
								
								illuaminate.sexp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								illuaminate.sexp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
			
		||||
; -*- mode: Lisp;-*-
 | 
			
		||||
 | 
			
		||||
(sources
 | 
			
		||||
  /doc/stub/
 | 
			
		||||
  /doc/javadoc/
 | 
			
		||||
  /src/main/resources/*/computercraft/lua/bios.lua
 | 
			
		||||
  /src/main/resources/*/computercraft/lua/rom/
 | 
			
		||||
  /src/test/resources/test-rom)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(doc
 | 
			
		||||
  (title "CC: Tweaked")
 | 
			
		||||
  (index doc/index.md)
 | 
			
		||||
  (source-link https://github.com/SquidDev-CC/CC-Tweaked/blob/${commit}/${path}#L${line})
 | 
			
		||||
 | 
			
		||||
  (module-kinds
 | 
			
		||||
    (peripheral Peripherals))
 | 
			
		||||
 | 
			
		||||
  (library-path
 | 
			
		||||
    /doc/stub/
 | 
			
		||||
    /doc/javadoc/
 | 
			
		||||
 | 
			
		||||
    /src/main/resources/*/computercraft/lua/rom/apis
 | 
			
		||||
    /src/main/resources/*/computercraft/lua/rom/apis/command
 | 
			
		||||
    /src/main/resources/*/computercraft/lua/rom/apis/turtle
 | 
			
		||||
 | 
			
		||||
    /src/main/resources/*/computercraft/lua/rom/modules/main
 | 
			
		||||
    /src/main/resources/*/computercraft/lua/rom/modules/command
 | 
			
		||||
    /src/main/resources/*/computercraft/lua/rom/modules/turtle))
 | 
			
		||||
 | 
			
		||||
(at /
 | 
			
		||||
  (linters
 | 
			
		||||
    syntax:string-index
 | 
			
		||||
 | 
			
		||||
    ;; It'd be nice to avoid this, but right now there's a lot of instances of
 | 
			
		||||
    ;; it.
 | 
			
		||||
    -var:set-loop
 | 
			
		||||
 | 
			
		||||
    ;; It's useful to name arguments for documentation, so we allow this. It'd
 | 
			
		||||
    ;; be good to find a compromise in the future, but this works for now.
 | 
			
		||||
    -var:unused-arg)
 | 
			
		||||
 | 
			
		||||
  (lint
 | 
			
		||||
    (bracket-spaces
 | 
			
		||||
      (call no-space)
 | 
			
		||||
      (function-args no-space)
 | 
			
		||||
      (parens no-space)
 | 
			
		||||
      (table space)
 | 
			
		||||
      (index no-space))
 | 
			
		||||
 | 
			
		||||
    ;; colours imports from colors, and we don't handle that right now.
 | 
			
		||||
    ;; keys is entirely dynamic, so we skip it.
 | 
			
		||||
    (dynamic-modules colours keys)
 | 
			
		||||
 | 
			
		||||
    (globals
 | 
			
		||||
      :max
 | 
			
		||||
      _CC_DEFAULT_SETTINGS
 | 
			
		||||
      _CC_DISABLE_LUA51_FEATURES
 | 
			
		||||
      ;; Ideally we'd pick these up from bios.lua, but illuaminate currently
 | 
			
		||||
      ;; isn't smart enough.
 | 
			
		||||
      sleep write printError read rs)))
 | 
			
		||||
 | 
			
		||||
;; We disable the unused global linter in bios.lua and the APIs. In the future
 | 
			
		||||
;; hopefully we'll get illuaminate to handle this.
 | 
			
		||||
(at
 | 
			
		||||
  (/src/main/resources/*/computercraft/lua/bios.lua
 | 
			
		||||
   /src/main/resources/*/computercraft/lua/rom/apis/)
 | 
			
		||||
  (linters -var:unused-global)
 | 
			
		||||
  (lint (allow-toplevel-global true)))
 | 
			
		||||
 | 
			
		||||
;; Silence some variable warnings in documentation stubs.
 | 
			
		||||
(at (/doc/stub/ /doc/javadoc/)
 | 
			
		||||
  (linters -var:unused-global)
 | 
			
		||||
  (lint (allow-toplevel-global true)))
 | 
			
		||||
 | 
			
		||||
;; Suppress warnings for currently undocumented modules.
 | 
			
		||||
(at
 | 
			
		||||
  (; Java APIs
 | 
			
		||||
   /doc/stub/http.lua
 | 
			
		||||
   /doc/stub/os.lua
 | 
			
		||||
   /doc/stub/turtle.lua
 | 
			
		||||
   ; Java generated APIs
 | 
			
		||||
   /doc/javadoc/turtle.lua
 | 
			
		||||
   ; Peripherals
 | 
			
		||||
   /doc/javadoc/drive.lua
 | 
			
		||||
   /doc/javadoc/speaker.lua
 | 
			
		||||
   /doc/javadoc/printer.lua
 | 
			
		||||
   ; Lua APIs
 | 
			
		||||
   /src/main/resources/*/computercraft/lua/rom/apis/io.lua
 | 
			
		||||
   /src/main/resources/*/computercraft/lua/rom/apis/window.lua)
 | 
			
		||||
 | 
			
		||||
  (linters -doc:undocumented -doc:undocumented-arg -doc:undocumented-return))
 | 
			
		||||
 | 
			
		||||
;; These currently rely on unknown references.
 | 
			
		||||
(at
 | 
			
		||||
  (/src/main/resources/*/computercraft/lua/rom/apis/textutils.lua
 | 
			
		||||
   /src/main/resources/*/computercraft/lua/rom/modules/main/cc/completion.lua
 | 
			
		||||
   /src/main/resources/*/computercraft/lua/rom/modules/main/cc/shell/completion.lua
 | 
			
		||||
   /src/main/resources/*/computercraft/lua/rom/programs/shell.lua
 | 
			
		||||
   /doc/stub/fs.lua)
 | 
			
		||||
  (linters -doc:unresolved-reference))
 | 
			
		||||
 | 
			
		||||
(at /src/test/resources/test-rom
 | 
			
		||||
  ; We should still be able to test deprecated members.
 | 
			
		||||
  (linters -var:deprecated)
 | 
			
		||||
 | 
			
		||||
  (lint
 | 
			
		||||
    (globals
 | 
			
		||||
      :max sleep write
 | 
			
		||||
      cct_test describe expect howlci fail it pending stub)))
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@@ -1,19 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<classpath>
 | 
			
		||||
	<classpathentry kind="src" path="src/core"/>
 | 
			
		||||
	<classpathentry excluding="org/luaj/vm2/luajc/antlr/|org/luaj/vm2/luajc/lst/|org/luaj/vm2/luajc/JavaCodeGenerator.java" kind="src" path="src/jse"/>
 | 
			
		||||
	<classpathentry kind="src" path="src/jme"/>
 | 
			
		||||
	<classpathentry kind="src" path="test/java"/>
 | 
			
		||||
	<classpathentry kind="src" path="test/junit"/>
 | 
			
		||||
	<classpathentry kind="src" path="test/lua"/>
 | 
			
		||||
	<classpathentry kind="src" path="examples/jse"/>
 | 
			
		||||
	<classpathentry kind="src" path="examples/jme"/>
 | 
			
		||||
	<classpathentry kind="src" path="examples/lua"/>
 | 
			
		||||
	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 | 
			
		||||
	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
 | 
			
		||||
	<classpathentry kind="lib" path="lib/midpapi20.jar"/>
 | 
			
		||||
	<classpathentry kind="lib" path="lib/cldcapi11.jar"/>
 | 
			
		||||
	<classpathentry kind="lib" path="lib/bcel-5.2.jar"/>
 | 
			
		||||
	<classpathentry kind="var" path="JRE_LIB"/>
 | 
			
		||||
	<classpathentry kind="output" path="bin"/>
 | 
			
		||||
</classpath>
 | 
			
		||||
@@ -1,17 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<projectDescription>
 | 
			
		||||
	<name>luaj-vm</name>
 | 
			
		||||
	<comment></comment>
 | 
			
		||||
	<projects>
 | 
			
		||||
	</projects>
 | 
			
		||||
	<buildSpec>
 | 
			
		||||
		<buildCommand>
 | 
			
		||||
			<name>org.eclipse.jdt.core.javabuilder</name>
 | 
			
		||||
			<arguments>
 | 
			
		||||
			</arguments>
 | 
			
		||||
		</buildCommand>
 | 
			
		||||
	</buildSpec>
 | 
			
		||||
	<natures>
 | 
			
		||||
		<nature>org.eclipse.jdt.core.javanature</nature>
 | 
			
		||||
	</natures>
 | 
			
		||||
</projectDescription>
 | 
			
		||||
@@ -1,780 +0,0 @@
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
<title>Getting Started with LuaJ</title>
 | 
			
		||||
<link rel="stylesheet" type="text/css" href="http://www.lua.org/lua.css">
 | 
			
		||||
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
<h1>
 | 
			
		||||
<a href="README.html"><img src="http://sourceforge.net/dbimage.php?id=196139" alt="" border="0"></a>
 | 
			
		||||
 | 
			
		||||
Getting Started with LuaJ
 | 
			
		||||
 | 
			
		||||
</h1>
 | 
			
		||||
James Roseborough, Ian Farmer, Version 2.0.3
 | 
			
		||||
<p>
 | 
			
		||||
<small>
 | 
			
		||||
Copyright © 2009-2012 Luaj.org.
 | 
			
		||||
Freely available under the terms of the
 | 
			
		||||
<a href="http://sourceforge.net/dbimage.php?id=196142">Luaj license</a>.
 | 
			
		||||
</small>
 | 
			
		||||
<hr>
 | 
			
		||||
<p>
 | 
			
		||||
 | 
			
		||||
<a href="#1">introduction</a>
 | 
			
		||||
·
 | 
			
		||||
<a href="#2">examples</a>
 | 
			
		||||
·
 | 
			
		||||
<a href="#3">concepts</a>
 | 
			
		||||
·
 | 
			
		||||
<a href="#4">libraries</a>
 | 
			
		||||
·
 | 
			
		||||
<a href="#5">luaj api</a>
 | 
			
		||||
·
 | 
			
		||||
<a href="#6">parser</a>
 | 
			
		||||
·
 | 
			
		||||
<a href="#7">building</a>
 | 
			
		||||
·
 | 
			
		||||
<a href="#8">downloads</a>
 | 
			
		||||
·
 | 
			
		||||
<a href="#9">release notes</a>
 | 
			
		||||
 | 
			
		||||
<!-- ====================================================================== -->
 | 
			
		||||
<p>
 | 
			
		||||
 | 
			
		||||
<h1>1 - <a name="1">Introduction</a></h1>
 | 
			
		||||
<h2>Goals of Luaj</h2>
 | 
			
		||||
Luaj is a lua interpreter based on the 5.1.x version of lua with the following goals in mind:
 | 
			
		||||
<ul>
 | 
			
		||||
<li>Java-centric implementation of lua vm built to leverage standard Java features.
 | 
			
		||||
<li>Lightweight, high performance execution of lua. 
 | 
			
		||||
<li>Multi-platform to be able to run on JME, JSE, or JEE environments. 
 | 
			
		||||
<li>Complete set of libraries and tools for integration into real-world projects.
 | 
			
		||||
<li>Dependable due to sufficient unit testing of vm and library features. 
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
<h2>Differences with 1.0</h2>
 | 
			
		||||
In addition to the basic goals of luaj, version 2.0 is aimed 
 | 
			
		||||
at improving on the 1.0 vm in the following aspects. 
 | 
			
		||||
<ul>
 | 
			
		||||
<li>Support for compiling lua source code into Java source code.
 | 
			
		||||
<li>Support for compiling lua bytecode directly into Java bytecode.
 | 
			
		||||
<li>Improved performance of of lua bytecode processing.
 | 
			
		||||
<li>Stackless vm design centered around dynamically typed objects.
 | 
			
		||||
<li>More alignment with C API (see <a href="names.csv">names.csv</a> for details)
 | 
			
		||||
<li>Improved class and package naming conventions. 
 | 
			
		||||
<li>Improved unit tests of core classes. 
 | 
			
		||||
<li>Improved quality due to major redesign and rewrite of core elements. 
 | 
			
		||||
<li>More complete implementation including weak keys and values, and all metatags. 
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
<h2>Performance</h2>
 | 
			
		||||
Good performance is a major goal of luaj.  
 | 
			
		||||
The following table provides measured execution times on a subset of benchmarks from 
 | 
			
		||||
<a href="http://shootout.alioth.debian.org/">the computer language benchmarks game</a>  
 | 
			
		||||
in comparison with the standard C distribution. 
 | 
			
		||||
<table cellspacing="10"><tr><td><table>
 | 
			
		||||
<tr valign="top">
 | 
			
		||||
	<td><u>Project</td>
 | 
			
		||||
	<td><u>Version</td>
 | 
			
		||||
	<td><u>Mode</td>
 | 
			
		||||
	<td rowspan="9">  </td>
 | 
			
		||||
	<td colspan="4" align="center"><u>Benchmark execution time (sec)</td>
 | 
			
		||||
	<td rowspan="9">  </td>
 | 
			
		||||
	<td><u>Language</td>
 | 
			
		||||
	<td><u>Sample command</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
<tr valign="top">
 | 
			
		||||
	<td colspan="2"></td>
 | 
			
		||||
	<td></td>
 | 
			
		||||
	<td><em>binarytrees 15</em></td>
 | 
			
		||||
	<td><em>fannkuch 10</em></td>
 | 
			
		||||
	<td><em>nbody 1e6</em></td>
 | 
			
		||||
	<td><em>nsieve 9</em></td>
 | 
			
		||||
	</tr>
 | 
			
		||||
<tr valign="top">
 | 
			
		||||
	<td>luaj</td>
 | 
			
		||||
	<td>2.0</td>
 | 
			
		||||
	<td>-b (luajc)</td>
 | 
			
		||||
	<td>2.980</td>
 | 
			
		||||
	<td>5.073</td>
 | 
			
		||||
	<td>16.794</td>
 | 
			
		||||
	<td>11.274</td>
 | 
			
		||||
	<td>Java</td>
 | 
			
		||||
	<td>java -cp luaj-jse-2.0.3.jar;bcel-5.2.jar lua <b>-b</b> fannkuch.lua 10</td></tr>
 | 
			
		||||
<tr valign="top">
 | 
			
		||||
	<td></td>
 | 
			
		||||
	<td></td>
 | 
			
		||||
	<td>-j (lua2java)</td>
 | 
			
		||||
	<td>4.463</td>
 | 
			
		||||
	<td>5.884</td>
 | 
			
		||||
	<td>16.701</td>
 | 
			
		||||
	<td>13.789</td>
 | 
			
		||||
	<td></td>
 | 
			
		||||
	<td>java -cp luaj-jse-2.0.3.jar lua <b>-j</b> fannkuch.lua 10</td></tr>
 | 
			
		||||
<tr valign="top">
 | 
			
		||||
	<td></td>
 | 
			
		||||
	<td></td>
 | 
			
		||||
	<td>-n (interpreted)</td>
 | 
			
		||||
	<td>12.838</td>
 | 
			
		||||
	<td>23.290</td>
 | 
			
		||||
	<td>36.894</td>
 | 
			
		||||
	<td>15.163</td>
 | 
			
		||||
	<td></td>
 | 
			
		||||
	<td>java -cp luaj-jse-2.0.3.jar lua -n fannkuch.lua 10</td></tr>
 | 
			
		||||
<tr valign="top">
 | 
			
		||||
	<td>lua</td>
 | 
			
		||||
	<td>5.1.4</td>
 | 
			
		||||
	<td></td>
 | 
			
		||||
	<td>17.637</td>
 | 
			
		||||
	<td>16.044</td>
 | 
			
		||||
	<td>15.201</td>
 | 
			
		||||
	<td>5.477</td>
 | 
			
		||||
	<td>C</td>
 | 
			
		||||
	<td>lua fannkuch.lua 10</td></tr>
 | 
			
		||||
<tr valign="top">
 | 
			
		||||
	<td>jill</td>
 | 
			
		||||
	<td>1.0.1</td>
 | 
			
		||||
	<td></td>
 | 
			
		||||
	<td>44.512</td>
 | 
			
		||||
	<td>54.630</td>
 | 
			
		||||
	<td>72.172</td>
 | 
			
		||||
	<td>20.779</td>
 | 
			
		||||
	<td>Java</td>
 | 
			
		||||
	<td></td></tr>
 | 
			
		||||
<tr valign="top">
 | 
			
		||||
	<td>kahlua</td>
 | 
			
		||||
	<td>1.0</td>
 | 
			
		||||
	<td>jse</td>
 | 
			
		||||
	<td>22.963</td>
 | 
			
		||||
	<td>63.277</td>
 | 
			
		||||
	<td>68.223</td>
 | 
			
		||||
	<td>21.529</td>
 | 
			
		||||
	<td>Java</td>
 | 
			
		||||
	<td></td></tr>
 | 
			
		||||
<tr valign="top">
 | 
			
		||||
	<td>mochalua</td>
 | 
			
		||||
	<td>1.0</td>
 | 
			
		||||
	<td></td>
 | 
			
		||||
	<td>50.457</td>
 | 
			
		||||
	<td>70.368</td>
 | 
			
		||||
	<td>82.868</td>
 | 
			
		||||
	<td>41.262</td>
 | 
			
		||||
	<td>Java</td>
 | 
			
		||||
	<td></td></tr>
 | 
			
		||||
</table></td></tr></table>
 | 
			
		||||
 | 
			
		||||
Luaj in interpreted mode performs well for the benchmarks, and even better when source-to-source (lua2java) 
 | 
			
		||||
or bytecode-to-bytecode (luajc) compilers are used, 
 | 
			
		||||
and actually executes <em>faster</em> than C-based lua in some cases.  
 | 
			
		||||
It is also faster than Java-lua implementations Jill, Kahlua, and Mochalua for all benchmarks tested.  
 | 
			
		||||
 | 
			
		||||
<h1>2 - <a name="2">Simple Examples</a></h1>
 | 
			
		||||
 | 
			
		||||
<h2>Run a lua script in Java SE</h2>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
From the main distribution directory line type:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
	java -cp lib/luaj-jse-2.0.3.jar lua examples/lua/hello.lua
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
You should see the following output:
 | 
			
		||||
<pre>
 | 
			
		||||
	hello, world
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
To see how luaj can be used to acccess most Java API's including swing, try:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
	java -cp lib/luaj-jse-2.0.3.jar lua examples/lua/swingapp.lua
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h2>Compile lua source to lua bytecode</h2>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
From the main distribution directory line type:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
	java -cp lib/luaj-jse-2.0.3.jar luac examples/lua/hello.lua
 | 
			
		||||
	java -cp lib/luaj-jse-2.0.3.jar lua luac.out
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The compiled output "luac.out" is lua bytecode and should run and produce the same result.
 | 
			
		||||
 | 
			
		||||
<h2>Compile lua source to java source</h2>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
Luaj can compile to lua source code to Java source code:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
	java -cp lib/luaj-jse-2.0.3.jar lua2java -s examples/lua -d . hello.lua
 | 
			
		||||
	javac -cp lib/luaj-jse-2.0.3.jar hello.java
 | 
			
		||||
	java -cp "lib/luaj-jse-2.0.3.jar;." lua -l hello
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The output <em>hello.java</em> is Java source, that implements the logic in hello.lua directly.
 | 
			
		||||
Once <em>hello.java</em> is compiled into <em>hello.class</em> it can be required and used in place of the original lua script, but with better performance.  
 | 
			
		||||
There are no additional dependencies for compiling or running source-to-source compiled lua. 
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-j</em></b> option when run in JDK 1.5 or higher:
 | 
			
		||||
<pre>
 | 
			
		||||
	java -cp lib/luaj-jse-2.0.3.jar lua -j examples/lua/hello.lua
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h2>Compile lua bytecode to java bytecode</h2>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
Luaj can compile lua sources or binaries directly to java bytecode if the bcel library is on the class path. From the main distribution directory line type:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
	ant bcel-lib
 | 
			
		||||
	java -cp "lib/luaj-jse-2.0.3.jar;lib/bcel-5.2.jar" luajc -s examples/lua -d . hello.lua
 | 
			
		||||
	java -cp "lib/luaj-jse-2.0.3.jar;." lua -l hello
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The output <em>hello.class</em> is Java bytecode, should run and produce the same result.
 | 
			
		||||
There is no runtime dependency on the bcel library, 
 | 
			
		||||
but the compiled classes must be in the class path at runtime, unless runtime jit-compiling via luajc and bcel are desired (see later sections).
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-b</em></b> option and providing the <em>bcel</em> library in the class path:
 | 
			
		||||
<pre>
 | 
			
		||||
	java -cp "lib/luaj-jse-2.0.3.jar;lib/bcel-5.2.jar" lua -b examples/lua/hello.lua
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h2>Run a script in a Java Application</h2>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The following pattern is used within Java SE
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
	import org.luaj.vm2.*;
 | 
			
		||||
	import org.luaj.vm2.lib.jse.*;
 | 
			
		||||
 | 
			
		||||
	String script = "examples/lua/hello.lua";
 | 
			
		||||
	LuaValue _G = JsePlatform.standardGlobals();
 | 
			
		||||
	_G.get("dofile").call( LuaValue.valueOf(script) );
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
A simple example may be found in
 | 
			
		||||
<pre>
 | 
			
		||||
	examples/jse/SampleJseMain.java
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
You must include the library <b>lib/luaj-jse-2.0.3.jar</b> in your class path.
 | 
			
		||||
 | 
			
		||||
<h2>Run a script in a MIDlet</h2>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The for MIDlets the <em>JmePlatform</em> is used instead:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
	import org.luaj.vm2.*;
 | 
			
		||||
	import org.luaj.vm2.lib.jme.*;
 | 
			
		||||
 | 
			
		||||
	String script = "examples/lua/hello.lua";
 | 
			
		||||
	LuaValue _G = JmePlatform.standardGlobals();
 | 
			
		||||
	_G.get("dofile").call( LuaValue.valueOf(script) );
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The file must be a resource within within the midlet jar for <em>dofile()</em> to find it.
 | 
			
		||||
Any files included via <em>require()</em> must also be part of the midlet resources.
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
A simple example may be found in
 | 
			
		||||
<pre>
 | 
			
		||||
	examples/jme/SampleMIDlet.java
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
You must include the library <b>lib/luaj-jme-2.0.3.jar</b> in your midlet jar.
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
An ant script to build and run the midlet is in
 | 
			
		||||
<pre>
 | 
			
		||||
	build-midlet.xml
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
You must install the wireless toolkit and define <em>WTK_HOME</em> for this script to work. 
 | 
			
		||||
 | 
			
		||||
<h2>Run a script using JSR-223 Dynamic Scripting</h2>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The standard use of JSR-223 scripting engines may be used:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
	ScriptEngineManager mgr = new ScriptEngineManager();
 | 
			
		||||
	ScriptEngine e = mgr.getEngineByExtension(".lua");
 | 
			
		||||
	e.put("x", 25);
 | 
			
		||||
	e.eval("y = math.sqrt(x)");
 | 
			
		||||
	System.out.println( "y="+e.get("y") );
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
All standard aspects of script engines including compiled statements should be supported.
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
You must include the library <b>lib/luaj-jse-2.0.3.jar</b> in your class path.
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
A working example may be found in
 | 
			
		||||
<pre>
 | 
			
		||||
	examples/jse/ScriptEngineSample.java
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
To compile and run it using Java 1.6 or higher:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
	javac examples/jse/ScriptEngineSample.java
 | 
			
		||||
	java -cp "lib/luaj-jse-2.0.3.jar;examples/jse" ScriptEngineSample
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h2>Excluding the lua bytecode compiler</h2>
 | 
			
		||||
 | 
			
		||||
By default, the compiler is included whenever <em>standardGlobals()</em> or <em>debugGlobals()</em> are called.  
 | 
			
		||||
Without a compiler, files can still be executed, but they must be compiled elsewhere beforehand.
 | 
			
		||||
The "luac" utility is provided in the jse jar for this purpose, or a standard lua compiler can be used.  
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
To exclude the lua-to-lua-bytecode compiler, do not call 
 | 
			
		||||
<em>standardGlobals()</em> or <em>debugGlobals()</em> 
 | 
			
		||||
but instead initialize globals with including only those libraries 
 | 
			
		||||
that are needed and omitting the line:
 | 
			
		||||
<pre>
 | 
			
		||||
	org.luaj.vm2.compiler.LuaC.install();
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h2>Including the Lua2Java lua-source-to-Java-source compiler</h2>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
To compile from lua sources to Java sources for all lua loaded at runtime, 
 | 
			
		||||
install the Lua2Java compiler <em>after</em> globals have been created using:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
	org.luaj.vm2.jse.lua2java.Lua2Java.install();
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
This uses the system Java compiler to compile from Java source to Java bytecode, 
 | 
			
		||||
and cannot compile lua binary files containing lua bytecode at runtime. 
 | 
			
		||||
 | 
			
		||||
<h2>Including the LuaJC lua-bytecode-to-Java-bytecode compiler</h2>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
To compile from lua to Java bytecode for all lua loaded at runtime, 
 | 
			
		||||
install the LuaJC compiler <em>after</em> globals have been created using:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
	org.luaj.vm2.jse.luajc.LuaJC.install();
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
This will compile all lua bytecode into Java bytecode, regardless of if they are loaded as
 | 
			
		||||
lua source or lua binary files.
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The requires <em>bcel</em> to be on the class path, and the ClassLoader of JSE or CDC.  
 | 
			
		||||
 | 
			
		||||
<h1>3 - <a name="3">Concepts</a></h1>
 | 
			
		||||
 | 
			
		||||
<h2>Globals</h2>
 | 
			
		||||
The old notion of platform has been replaced with creation of globals. 
 | 
			
		||||
Two classes are provided to encapsulate common combinations of libraries.  
 | 
			
		||||
 | 
			
		||||
<h3>JsePlatform</h3>
 | 
			
		||||
 | 
			
		||||
This class can be used as a factory for globals in a typical Java SE application. 
 | 
			
		||||
All standard libraries are included, as well as the luajava library. 
 | 
			
		||||
The default search path is the current directory,
 | 
			
		||||
and the math operations include all those supported by Java SE.
 | 
			
		||||
 | 
			
		||||
<h3>JmePlatform</h3>
 | 
			
		||||
 | 
			
		||||
This class can be used to set up the basic environment for a Java ME application.
 | 
			
		||||
The default search path is limited to the jar resources,
 | 
			
		||||
and the math operations are limited to those supported by Java ME.
 | 
			
		||||
All libraries are included except luajava, and the os, io, and math libraries are 
 | 
			
		||||
limited to those functions that can be supported on that platform.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h1>4 - <a name="4">Libraries</a></h1>
 | 
			
		||||
 | 
			
		||||
<h2>Standard Libraries</h2>
 | 
			
		||||
 | 
			
		||||
Libraries are coded to closely match the behavior specified in 
 | 
			
		||||
See <a href="http://www.lua.org/manual/5.1/">standard lua documentation</a> for details on the library API's
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The following libraries are loaded by both <em>JsePlatform.standardGlobals()</em> and <em>JmePlatform.standardGlobals()</em>:
 | 
			
		||||
<pre>	base
 | 
			
		||||
	coroutine
 | 
			
		||||
	io
 | 
			
		||||
	math
 | 
			
		||||
	os
 | 
			
		||||
	package
 | 
			
		||||
	string
 | 
			
		||||
	table
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The <em>JsePlatform.standardGlobals()</em> globals also include:
 | 
			
		||||
<pre>	luajava 
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The <em>JsePlatform.debugGlobals()</em> and <em>JsePlatform.debugGlobals()</em> functions produce globals that include:
 | 
			
		||||
<pre>	debug
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h3>I/O Library</h3>
 | 
			
		||||
The implementation of the <em>io</em> library differs by platform owing to platform limitations.
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The <em>JmePlatform.standardGlobals()</em> instantiated the io library <em>io</em> in 
 | 
			
		||||
<pre>
 | 
			
		||||
	src/jme/org/luaj/vm2/lib/jme/JmeIoLib.java
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
The <em>JsePlatform.standardGlobals()</em> includes support for random access and is in 
 | 
			
		||||
<pre>
 | 
			
		||||
	src/jse/org/luaj/vm2/lib/jse/JseIoLib.java
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h3>OS Library</h3>
 | 
			
		||||
The implementation of the <em>os</em> library also differs per platform.
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The basic <em>os</em> library implementation us used by <em>JmePlatform</em> and is in:
 | 
			
		||||
<pre>
 | 
			
		||||
	src/core/org/luaj/lib/OsLib.java
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
A richer version for use by <em>JsePlatform</em> is : 
 | 
			
		||||
<pre>
 | 
			
		||||
	src/jse/org/luaj/vm2/lib/jse/JseOsLib.java
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
Time is a represented as number of milliseconds since the epoch, 
 | 
			
		||||
and most time and date formatting, locales, and other features 
 | 
			
		||||
are not implemented.
 | 
			
		||||
 | 
			
		||||
<h3>Coroutine Library</h3>
 | 
			
		||||
The <em>coroutine</em> library is implemented using one JavaThread per coroutine.   
 | 
			
		||||
This allows <em>coroutine.yield()</em> can be called from anywhere, 
 | 
			
		||||
as with the yield-from-anywhere patch in C-based lua. 
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
Luaj uses WeakReferences and the OrphanedThread error to ensure that coroutines that are no longer referenced 
 | 
			
		||||
are properly garbage collected.  For thread safety, OrphanedThread should not be caught by Java code.  
 | 
			
		||||
See <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/LuaThread.html">LuaThread</a>
 | 
			
		||||
and <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/OrphanedThread.html">OrphanedThread</a>
 | 
			
		||||
javadoc for details. 
 | 
			
		||||
 | 
			
		||||
<h3>Debug Library</h3>
 | 
			
		||||
The <em>debug</em> library is not included by default by 
 | 
			
		||||
<em>JmePlatform.standardGlobals()</em> or <em>JsePlatform.standardGlobsls()</em> .
 | 
			
		||||
 | 
			
		||||
The functions <em>JmePlatform.debugGlobals()</em> and <em>JsePlatform.debugGlobsls()</em> 
 | 
			
		||||
create globals that contain the debug library in addition to the other standard libraries. 
 | 
			
		||||
 | 
			
		||||
To install dynamically from lua use java-class-based require:</em>:
 | 
			
		||||
<pre>
 | 
			
		||||
	require 'org.luaj.vm2.lib.DebugLib'
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
The <em>lua</em> command line utility includes the <em>debug</em> library by default.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h3>The Luajava Library</h3>
 | 
			
		||||
The <em>JsePlatform.standardGlobals()</em> includes the <em>luajava</em> library, which simplifies binding to Java classes and methods.  
 | 
			
		||||
It is patterned after the original <a href="http://www.keplerproject.org/luajava/">luajava project</a>.
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The following lua script will open a swing frame on Java SE:
 | 
			
		||||
<pre>
 | 
			
		||||
	jframe = luajava.bindClass( "javax.swing.JFrame" )
 | 
			
		||||
	frame = luajava.newInstance( "javax.swing.JFrame", "Texts" );
 | 
			
		||||
	frame:setDefaultCloseOperation(jframe.EXIT_ON_CLOSE)
 | 
			
		||||
	frame:setSize(300,400)
 | 
			
		||||
	frame:setVisible(true)
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
See a longer sample in <em>examples/lua/swingapp.lua</em> for details, including a simple animation loop, rendering graphics, mouse and key handling, and image loading. 
 | 
			
		||||
Or try running it using: 
 | 
			
		||||
<pre>
 | 
			
		||||
	java -cp lib/luaj-jse-2.0.3.jar lua examples/lua/swingapp.lua
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The Java ME platform does not include this library, and it cannot be made to work because of the lack of a reflection API in Java ME. 
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The <em>lua</em> connand line tool includes <em>luajava</em>. 
 | 
			
		||||
 | 
			
		||||
<h1>5 - <a name="5">LuaJ API</a></h1>
 | 
			
		||||
 | 
			
		||||
<h2>API Javadoc</h2>
 | 
			
		||||
The javadoc for the main classes in the LuaJ API are on line at
 | 
			
		||||
<pre>
 | 
			
		||||
	 <a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sourceforge.net/api/2.0</a>
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
You can also build a local version from sources using 
 | 
			
		||||
<pre>
 | 
			
		||||
	 ant doc
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h2>LuaValue and Varargs</h2>
 | 
			
		||||
All lua value manipulation is now organized around 
 | 
			
		||||
<a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/LuaValue.html">LuaValue</a>
 | 
			
		||||
which exposes the majority of interfaces used for lua computation.  
 | 
			
		||||
<pre>
 | 
			
		||||
	 <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/LuaValue.html">org.luaj.vm2.LuaValue</a>
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h3>Common Functions</h3>
 | 
			
		||||
<em>LuaValue</em> exposes functions for each of the operations in LuaJ.  
 | 
			
		||||
Some commonly used functions and constants include:
 | 
			
		||||
<pre>
 | 
			
		||||
	call();               // invoke the function with no arguments
 | 
			
		||||
	call(LuaValue arg1);  // call the function with 1 argument
 | 
			
		||||
	invoke(Varargs arg);  // call the function with variable arguments, variable return values
 | 
			
		||||
	get(int index);       // get a table entry using an integer key
 | 
			
		||||
	get(LuaValue key);    // get a table entry using an arbitrary key, may be a LuaInteger
 | 
			
		||||
	rawget(int index);    // raw get without metatable calls
 | 
			
		||||
	valueOf(int i);       // return LuaValue corresponding to an integer
 | 
			
		||||
	valueOf(String s);    // return LuaValue corresponding to a String
 | 
			
		||||
	toint();              // return value as a Java int
 | 
			
		||||
	tojstring();          // return value as a Java String
 | 
			
		||||
	isnil();              // is the value nil
 | 
			
		||||
	NIL;                  // the value nil
 | 
			
		||||
	NONE;                 // a Varargs instance with no values	 
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h2>Varargs</h2>
 | 
			
		||||
The interface <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/Varargs.html">Varargs</a> provides an abstraction for 
 | 
			
		||||
both a variable argument list and multiple return values.  
 | 
			
		||||
For convenience, <em>LuaValue</em> implements <em>Varargs</em> so a single value can be supplied anywhere 
 | 
			
		||||
variable arguments are expected.      
 | 
			
		||||
<pre>
 | 
			
		||||
	 <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/Varargs.html">org.luaj.vm2.Varargs</a>
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h3>Common Functions</h3>
 | 
			
		||||
<em>Varargs</em> exposes functions for accessing elements, and coercing them to specific types:
 | 
			
		||||
<pre>
 | 
			
		||||
	narg();                 // return number of arguments
 | 
			
		||||
	arg1();                 // return the first argument
 | 
			
		||||
	arg(int n);             // return the nth argument
 | 
			
		||||
	isnil(int n);           // true if the nth argument is nil
 | 
			
		||||
	checktable(int n);      // return table or throw error
 | 
			
		||||
	optlong(int n,long d);  // return n if a long, d if no argument, or error if not a long
 | 
			
		||||
</pre>
 | 
			
		||||
 
 | 
			
		||||
See the <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/Varargs.html">Varargs</a> API for a complete list.
 | 
			
		||||
 
 | 
			
		||||
<h2>LibFunction</h2>
 | 
			
		||||
The simplest way to implement a function is to choose a base class based on the number of arguments to the function.
 | 
			
		||||
LuaJ provides 5 base classes for this purpose, depending if the function has 0, 1, 2, 3 or variable arguments, 
 | 
			
		||||
and if it provide multiple return values.   
 | 
			
		||||
<pre>
 | 
			
		||||
	 <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/ZeroArgFunction.html">org.luaj.vm2.lib.ZeroArgFunction</a>
 | 
			
		||||
	 <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/OneArgFunction.html">org.luaj.vm2.lib.OneArgFunction</a>
 | 
			
		||||
	 <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/TwoArgFunction.html">org.luaj.vm2.lib.TwoArgFunction</a>
 | 
			
		||||
	 <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/ThreeArgFunction.html">org.luaj.vm2.lib.ThreeArgFunction</a>
 | 
			
		||||
	 <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/VarArgFunction.html">org.luaj.vm2.lib.VarArgFunction</a>
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
Each of these functions has an abstract method that must be implemented, 
 | 
			
		||||
and argument fixup is done automatically by the classes as each Java function is invoked.
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
For example, to implement a "hello, world" function, we could supply:
 | 
			
		||||
<pre>
 | 
			
		||||
	pubic class hello extends ZeroArgFunction {
 | 
			
		||||
		public LuaValue call() {
 | 
			
		||||
			env.get("print").call(valueOf("hello, world"));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
The value <em>env</em> is the environment of the function, and is normally supplied 
 | 
			
		||||
by the instantiating object whenever default loading is used. 
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
Calling this function from lua could be done by:
 | 
			
		||||
<pre> 
 | 
			
		||||
	require( 'hello' )()
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
while calling this function from Java would look like:
 | 
			
		||||
<pre> 
 | 
			
		||||
	new hello().call();
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
Note that in both the lua and Java case, extra arguments will be ignored, and the function will be called.  
 | 
			
		||||
Also, no virtual machine instance is necessary to call the function. 
 | 
			
		||||
To allow for arguments, or return multiple values, extend one of the other base classes. 
 | 
			
		||||
 
 | 
			
		||||
<h2>Closures</h2>
 | 
			
		||||
Closures still exist in this framework, but are optional, and are only used to implement lua bytecode execution.  
 | 
			
		||||
 | 
			
		||||
<h1>6 - <a name="6">Parser</a></h1>
 | 
			
		||||
 | 
			
		||||
<h2>Javacc Grammar</h2>
 | 
			
		||||
A Javacc grammarwas developed to simplify the creation of Java-based parsers for the lua language.
 | 
			
		||||
The grammar is specified for <a href="https://javacc.dev.java.net/">javacc version 5.0</a> because that tool generates standalone 
 | 
			
		||||
parsers that do not require a separate runtime.     
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
A plain undecorated grammer that can be used for validation is available in <a href="grammar/Lua51.jj">grammar/Lua51.jj</a>
 | 
			
		||||
while a grammar that generates a typed parse tree is in  <a href="grammar/LuaParser.jj">grammar/LuaParser.jj</a>
 | 
			
		||||
 | 
			
		||||
<h2>Creating a Parse Tree from Lua Source</h2>
 | 
			
		||||
The default lu compiler does a single-pass compile of lua source to lua bytecode, so no explicit parse tree is produced.  
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
To simplify the creation of abstract syntax trees from lua sources, the LuaParser class is generated as part of the JME build.  
 | 
			
		||||
To use it, provide an input stream, and invoke the root generator, which will return a Chunk if the file is valid, 
 | 
			
		||||
or throw a ParseException if there is a syntax error.
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
For example, to parse a file and print all variable names, use code like:
 | 
			
		||||
<pre>
 | 
			
		||||
	try {
 | 
			
		||||
		String file = "main.lua";
 | 
			
		||||
		LuaParser parser = new LuaParser(new FileInputStream(file));
 | 
			
		||||
		Chunk chunk = parser.Chunk();
 | 
			
		||||
		chunk.accept( new Visitor() {
 | 
			
		||||
			public void visit(Exp.NameExp exp) {
 | 
			
		||||
				System.out.println("Name in use: "+exp.name.name);
 | 
			
		||||
			}
 | 
			
		||||
		} );
 | 
			
		||||
	} catch ( ParseException e ) {
 | 
			
		||||
		System.out.println("parse failed: " + e.getMessage() + "\n"
 | 
			
		||||
			+ "Token Image: '" + e.currentToken.image + "'\n"
 | 
			
		||||
			+ "Location: " + e.currentToken.beginLine + ":" + e.currentToken.beginColumn 
 | 
			
		||||
			         + "-" + e.currentToken.endLine + "," + e.currentToken.endColumn);
 | 
			
		||||
	}
 | 
			
		||||
</pre> 
 | 
			
		||||
In luaj 2.0.3 error reporting was turned on in the parser so line numbers are avaiable for most parse exceptions.
 | 
			
		||||
This example may be found in
 | 
			
		||||
<pre>
 | 
			
		||||
	examples/jse/SampleParser.java
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
See the <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/ast/package-summary.html">org.luaj.vm2.ast package</a> javadoc for the API relating to the syntax tree that is produced. 
 | 
			
		||||
 | 
			
		||||
<h1>7 - <a name="7">Building and Testing</a></h1>
 | 
			
		||||
 | 
			
		||||
<h2>Building the jars</h2>
 | 
			
		||||
An ant file is included in the root directory which builds the libraries by default.
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
Other targets exist for creating distribution file an measuring code coverage of unit tests.
 | 
			
		||||
 | 
			
		||||
<h2>Unit tests</h2>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The main luaj JUnit tests are organized into a JUnit 3 suite:
 | 
			
		||||
<pre>
 | 
			
		||||
	test/junit/org/luaj/vm2/AllTests.lua
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
Unit test scripts can be found in these locations
 | 
			
		||||
<pre>
 | 
			
		||||
	test/lua/*.lua
 | 
			
		||||
	test/junit/org/luaj/vm2/compiler/lua5.1-tests.zip
 | 
			
		||||
	test/junit/org/luaj/vm2/compiler/regressions.zip
 | 
			
		||||
	test/junit/org/luaj/vm2/vm1/luajvm1-tests.zip
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h2>Code coverage</h2>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
A build script for running unit tests and producing code coverage statistics is in 
 | 
			
		||||
<pre>
 | 
			
		||||
	build-coverage.xml
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
It relies on the cobertura code coverage library.
 | 
			
		||||
 | 
			
		||||
<h1>8 - <a name="8">Downloads</a></h1>
 | 
			
		||||
 | 
			
		||||
<h2>Downloads and Project Pages</h2>
 | 
			
		||||
Downloads for all version available on SourceForge or LuaForge.  
 | 
			
		||||
Sources are hosted on SourceForge and available via sourceforge.net    
 | 
			
		||||
<br/>
 | 
			
		||||
<pre>
 | 
			
		||||
	<a href="http://luaj.sourceforge.net/">SourceForge Luaj Project Page</a>
 | 
			
		||||
	<a href="http://sourceforge.net/project/platformdownload.php?group_id=197627">SourceForge Luaj Download Area</a>
 | 
			
		||||
</pre>
 | 
			
		||||
<p/>
 | 
			
		||||
and LuaForge:
 | 
			
		||||
<pre>
 | 
			
		||||
	<a href="http://luaforge.net/projects/luaj/">LuaForge Luaj Project Page</a>
 | 
			
		||||
	<a href="http://luaforge.net/frs/?group_id=457">LuaForge Luaj Project Area</a>
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h1>9 - <a name="9">Release Notes</a></h1>
 | 
			
		||||
 | 
			
		||||
<h2>Main Changes by Version</h2>
 | 
			
		||||
<table cellspacing="10"><tr><td><table cellspacing="4">
 | 
			
		||||
<tr valign="top"><td>  <b>2.0</b></td><td><ul>
 | 
			
		||||
<li>Initial release of 2.0 version </li>  
 | 
			
		||||
</ul></td></tr>
 | 
			
		||||
<tr valign="top"><td>  <b>2.0.1</b></td><td><ul>
 | 
			
		||||
<li>Improve correctness of singleton construction related to static initialization </li>
 | 
			
		||||
<li>Fix nan-related error in constant folding logic that was failing on some JVMs </li>
 | 
			
		||||
<li>JSR-223 fixes: add META-INF/services entry in jse jar, improve bindings implementation </li>
 | 
			
		||||
</ul></td></tr>
 | 
			
		||||
<tr valign="top"><td>  <b>2.0.2</b></td><td><ul>
 | 
			
		||||
<li>JSR-223 bindings change: non Java-primitives will now be passed as LuaValue </li> 
 | 
			
		||||
<li>JSR-223 enhancement: allow both ".lua" and "lua" as extensions in getScriptEngine() </li>
 | 
			
		||||
<li>JSR-223 fix: use system class loader to support using luaj as JRE extension </li>
 | 
			
		||||
<li>Improve selection logic when binding to overloaded functions using luajava</li>
 | 
			
		||||
<li>Enhance javadoc, put it <a href="docs/api/index.html">in distribution</a> and <a href="http://luaj.sourceforge.net/api/2.0/index.html">on line</a></li>
 | 
			
		||||
<li>Major refactor of luajava type coercion logic, improve method selection.</li> 
 | 
			
		||||
<li>Add lib/luaj-sources-2.0.2.jar for easier integration into an IDE such as Netbeans </li>
 | 
			
		||||
<tr valign="top"><td>  <b>2.0.3</b></td><td><ul>
 | 
			
		||||
<li>Improve coroutine state logic including let unreferenced coroutines be garbage collected </li>
 | 
			
		||||
<li>Fix lua command vararg values passed into main script to match what is in global arg table </li>
 | 
			
		||||
<li>Add arithmetic metatag processing when left hand side is a number and right hand side has metatable </li>
 | 
			
		||||
<li>Fix load(func) when mutiple string fragments are supplied by calls to func </li>
 | 
			
		||||
<li>Allow access to public members of private inner classes where possible </li>
 | 
			
		||||
<li>Turn on error reporting in LuaParser so line numbers ar available in ParseException </li>
 | 
			
		||||
<li>Improve compatibility of table.remove() </li>
 | 
			
		||||
<li>Disallow base library setfenv() calls on Java functions </li>
 | 
			
		||||
</ul></td></tr>
 | 
			
		||||
</table></td></tr></table>
 | 
			
		||||
 | 
			
		||||
<h2>Known Issues</h2>
 | 
			
		||||
<ul>
 | 
			
		||||
<li>debug code may not be completely removed by some obfuscators
 | 
			
		||||
<li>tail calls are not tracked in debug information
 | 
			
		||||
<li>using both version 1 and 2 libraries together in the same java vm has not been tested
 | 
			
		||||
<li>module() and setfenv() only partially supported for lau2java or luajc compiled lua
 | 
			
		||||
<li>values associated with weak keys may linger longer than expected
 | 
			
		||||
<li>behavior of luaj when a SecurityManager is used has not been fully characterized
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
@@ -1,119 +0,0 @@
 | 
			
		||||
<project default="all" xmlns:artifact="antlib:org.apache.maven.artifact.ant">
 | 
			
		||||
	<!-- 
 | 
			
		||||
	Run code coverage for unit tests on the luaj vm and libraries.
 | 
			
		||||
	-->
 | 
			
		||||
 | 
			
		||||
	<property name="classes.dir" value="build/classes-debug" />
 | 
			
		||||
	<property name="instrumented.dir" value="build/instrumented" />
 | 
			
		||||
	<property name="reports.xml.dir" value="build/reports-junit-xml" />
 | 
			
		||||
	<property name="reports.html.dir" value="build/reports-junit-html" />
 | 
			
		||||
	<property name="coverage.xml.dir" value="build/reports-coverage-xml" />
 | 
			
		||||
	<property name="coverage.html.dir" value="build/reports-coverage-html" />
 | 
			
		||||
	<property name="cobertura.serfile" value="cobertura.ser" />
 | 
			
		||||
	<property name="cobertura.logfile" value="cobertura.log" />
 | 
			
		||||
 | 
			
		||||
	<artifact:dependencies filesetId="cobutura.fileset">
 | 
			
		||||
		<dependency groupId="net.sourceforge.cobertura" artifactId="cobertura" version="1.9.4.1"/>
 | 
			
		||||
		<dependency groupId="junit" artifactId="junit" version="3.8.1"/>
 | 
			
		||||
	</artifact:dependencies>
 | 
			
		||||
	
 | 
			
		||||
	<path id="cobertura.classpath">
 | 
			
		||||
		<fileset refid="cobutura.fileset" />
 | 
			
		||||
	</path>
 | 
			
		||||
	
 | 
			
		||||
	<taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
 | 
			
		||||
	
 | 
			
		||||
	<import file="wtk.xml"/>
 | 
			
		||||
	
 | 
			
		||||
	<property environment="env"/>
 | 
			
		||||
 | 
			
		||||
	<target name="clean" description="Remove all files created by the build/test process.">
 | 
			
		||||
		<delete dir="${classes.dir}" failonerror="yes"/>
 | 
			
		||||
		<delete dir="${instrumented.dir}" failonerror="yes"/>
 | 
			
		||||
		<delete file="${cobertura.logfile}" />
 | 
			
		||||
		<delete file="${cobertura.serfile}" />
 | 
			
		||||
	</target>
 | 
			
		||||
 | 
			
		||||
	<target name="init">
 | 
			
		||||
		<ant antfile="build.xml" target="bcel-lib"/>
 | 
			
		||||
		<ant antfile="build.xml" target="luaj1-lib"/>
 | 
			
		||||
		<mkdir dir="${classes.dir}" />
 | 
			
		||||
		<mkdir dir="${instrumented.dir}" />
 | 
			
		||||
		<mkdir dir="${reports.xml.dir}" />
 | 
			
		||||
		<mkdir dir="${reports.html.dir}" />
 | 
			
		||||
		<mkdir dir="${coverage.xml.dir}" />
 | 
			
		||||
		<mkdir dir="${coverage.html.dir}" />
 | 
			
		||||
	</target>
 | 
			
		||||
 | 
			
		||||
	<target name="compile" depends="init,wtk-or-fail">
 | 
			
		||||
		<javac destdir="${classes.dir}" debug="yes" target="1.5">
 | 
			
		||||
			<classpath refid="cobertura.classpath" />
 | 
			
		||||
		    <classpath refid="wtk-libs" />
 | 
			
		||||
		    <classpath path="lib/bcel-5.2.jar" />
 | 
			
		||||
		    <src path="src/core"/>
 | 
			
		||||
		    <src path="src/jme"/>
 | 
			
		||||
		    <src path="src/jse"/>
 | 
			
		||||
		    <src path="test/junit"/>
 | 
			
		||||
		</javac>
 | 
			
		||||
	</target>
 | 
			
		||||
 | 
			
		||||
	<target name="instrument" depends="compile">
 | 
			
		||||
		<delete file="${cobertura.serfile}"/>
 | 
			
		||||
		<delete dir="${instrumented.dir}" failonerror="no"/>
 | 
			
		||||
		<cobertura-instrument datafile="${cobertura.serfile}" todir="${instrumented.dir}">
 | 
			
		||||
			<fileset dir="${classes.dir}">
 | 
			
		||||
				<include name="org/luaj/vm2/*.class" />
 | 
			
		||||
				<include name="org/luaj/vm2/lib/*.class" />
 | 
			
		||||
				<include name="org/luaj/vm2/lib/jse/*.class" />
 | 
			
		||||
				<include name="org/luaj/vm2/lib/jme/*.class" />
 | 
			
		||||
				<include name="org/luaj/vm2/compiler/*.class" />
 | 
			
		||||
				<include name="org/luaj/vm2/luajc/*.class" />
 | 
			
		||||
				<include name="org/luaj/vm2/lua2java/*.class" />
 | 
			
		||||
				<include name="org/luaj/vm2/parser/*.class" />
 | 
			
		||||
				<include name="org/luaj/vm2/ast/*.class" />
 | 
			
		||||
				<exclude name="**/*Test*.class" />
 | 
			
		||||
			</fileset>
 | 
			
		||||
		</cobertura-instrument>
 | 
			
		||||
	</target>
 | 
			
		||||
 | 
			
		||||
	<target name="test">
 | 
			
		||||
		<junit fork="yes" dir="${basedir}" showoutput="yes">
 | 
			
		||||
     		<sysproperty key="net.sourceforge.cobertura.serfile" 
 | 
			
		||||
     			file="${basedir}/${cobertura.serfile}" />		    
 | 
			
		||||
			<classpath location="${instrumented.dir}" />
 | 
			
		||||
			<classpath location="${classes.dir}" />
 | 
			
		||||
			<classpath refid="cobertura.classpath" />
 | 
			
		||||
			<classpath location="test/lua" />
 | 
			
		||||
			<classpath location="test/junit/org/luaj/vm2/compiler" />
 | 
			
		||||
			<classpath location="test/junit/org/luaj/vm2/vm1" />
 | 
			
		||||
		    <classpath path="lib/bcel-5.2.jar" />
 | 
			
		||||
			<formatter type="xml" />
 | 
			
		||||
			<batchtest todir="${reports.xml.dir}">
 | 
			
		||||
				<fileset dir="test/junit">
 | 
			
		||||
					<include name="org/luaj/vm2/AllTests.java" />
 | 
			
		||||
				</fileset>
 | 
			
		||||
			</batchtest>
 | 
			
		||||
		</junit>
 | 
			
		||||
		
 | 
			
		||||
		<junitreport todir="${reports.xml.dir}">
 | 
			
		||||
			<fileset dir="${reports.xml.dir}">
 | 
			
		||||
				<include name="TEST-*.xml" />
 | 
			
		||||
			</fileset>
 | 
			
		||||
			<report format="frames" todir="${reports.html.dir}" />
 | 
			
		||||
		</junitreport>
 | 
			
		||||
	</target>
 | 
			
		||||
 | 
			
		||||
	<target name="report">
 | 
			
		||||
		<cobertura-report datafile="${cobertura.serfile}" destdir="${coverage.xml.dir}" format="xml" /> 
 | 
			
		||||
		<cobertura-report datafile="${cobertura.serfile}" destdir="${coverage.html.dir}">
 | 
			
		||||
			<fileset dir="src/core"/>
 | 
			
		||||
			<fileset dir="src/jse"/>
 | 
			
		||||
			<fileset dir="src/jme"/>
 | 
			
		||||
		</cobertura-report>
 | 
			
		||||
	</target>
 | 
			
		||||
 | 
			
		||||
	<target name="coverage" depends="clean,init,compile,instrument,test,report"/>
 | 
			
		||||
 | 
			
		||||
	<target name="all" depends="coverage" />
 | 
			
		||||
	
 | 
			
		||||
</project>
 | 
			
		||||
@@ -1,56 +0,0 @@
 | 
			
		||||
<project default="all-libs">
 | 
			
		||||
 | 
			
		||||
	<available file="lib/midpapi20.jar" property="midpapi.lib.exists"/>
 | 
			
		||||
	<available file="lib/bcel-5.2.jar" property="bcel.lib.exists"/>			
 | 
			
		||||
	<available file="lib/javacc.jar" property="javacc.lib.exists"/>			
 | 
			
		||||
	<available file="lib/proguard.jar" property="proguard.lib.exists"/>			
 | 
			
		||||
	<available file="lib/antenna-bin-1.2.0-beta.jar" property="antenna.lib.exists"/>			
 | 
			
		||||
	<available file="lib/junit.jar" property="junit.lib.exists"/>
 | 
			
		||||
	<available file="lib/cobertura.jar" property="cobertura.lib.exists"/>
 | 
			
		||||
	<available file="lib/microemulator.jar" property="microemulator.lib.exists"/>
 | 
			
		||||
 | 
			
		||||
	<macrodef name="download">
 | 
			
		||||
		<attribute name="zipname"/>
 | 
			
		||||
		<attribute name="jars" default="**/*.jar"/>
 | 
			
		||||
		<sequential>
 | 
			
		||||
			<mkdir dir="lib"/>
 | 
			
		||||
			<get src="http://luaj.sourceforge.net/lib/@{zipname}.tar.gz" 
 | 
			
		||||
				dest="lib/@{zipname}.tar.gz"/>
 | 
			
		||||
			<gunzip src="lib/@{zipname}.tar.gz" dest="lib/@{zipname}.tar"/>
 | 
			
		||||
			<untar src="lib/@{zipname}.tar" dest="lib" overwrite="true">
 | 
			
		||||
			    <patternset>
 | 
			
		||||
			        <include name="@{jars}"/>
 | 
			
		||||
			    </patternset>
 | 
			
		||||
			    <mapper type="flatten"/>
 | 
			
		||||
			</untar>
 | 
			
		||||
	   </sequential>
 | 
			
		||||
	</macrodef>
 | 
			
		||||
 | 
			
		||||
	<target name="wtk-libs" unless="midpapi.lib.exists">
 | 
			
		||||
		<download zipname="wtk-2.5.2-api"/>
 | 
			
		||||
	</target>
 | 
			
		||||
	<target name="bcel-lib" unless="bcel.lib.exists">
 | 
			
		||||
		<download zipname="/bcel-5.2"/>
 | 
			
		||||
	</target>
 | 
			
		||||
	<target name="javacc-lib" unless="javacc.lib.exists">
 | 
			
		||||
		<download zipname="javacc-5.0"/>
 | 
			
		||||
	</target>
 | 
			
		||||
	<target name="proguard-lib" unless="proguard.lib.exists">
 | 
			
		||||
		<download zipname="proguard4.6"/>
 | 
			
		||||
	</target>
 | 
			
		||||
	<target name="antenna-lib" unless="antenna.lib.exists">
 | 
			
		||||
		<download zipname="antenna-bin-1.2.0-beta"/>
 | 
			
		||||
	</target>
 | 
			
		||||
	<target name="junit-lib" unless="junit.lib.exists">
 | 
			
		||||
		<download zipname="junit-3.8.2"/>
 | 
			
		||||
	</target>
 | 
			
		||||
	<target name="cobertura-lib" unless="cobertura.lib.exists">
 | 
			
		||||
		<download zipname="cobertura-1.9.4.1-bin"/>
 | 
			
		||||
	</target>
 | 
			
		||||
	<target name="microemulator-lib" unless="microemulator.lib.exists">
 | 
			
		||||
		<download zipname="microemulator-2.0.4" jars="**/microemulator.jar"/>
 | 
			
		||||
	</target>
 | 
			
		||||
 | 
			
		||||
	<target name="all-libs" depends="wtk-libs,bcel-lib,javacc-lib,proguard-lib,antenna-lib,junit-lib,cobertura-lib"/>
 | 
			
		||||
	
 | 
			
		||||
</project>
 | 
			
		||||
@@ -1,172 +0,0 @@
 | 
			
		||||
<project default="all">
 | 
			
		||||
	<property file="version.properties"/>
 | 
			
		||||
		
 | 
			
		||||
	<property name="jar.name.jme" value="luaj-jme-${version}.jar"/>
 | 
			
		||||
	<property name="jar.name.jse" value="luaj-jse-${version}.jar"/>
 | 
			
		||||
	<property name="jar.name.sources" value="luaj-sources-${version}.jar"/>
 | 
			
		||||
 | 
			
		||||
	<target name="clean">
 | 
			
		||||
		<delete dir="build"/>
 | 
			
		||||
		<delete>
 | 
			
		||||
		    <fileset dir="." includes="luaj-*.jar"/>
 | 
			
		||||
		</delete>
 | 
			
		||||
	</target>
 | 
			
		||||
 | 
			
		||||
	<import file="build-libs.xml"/>
 | 
			
		||||
 | 
			
		||||
	<target name="parser" depends="javacc-lib">
 | 
			
		||||
		<java classname="javacc" classpath="lib/javacc.jar">
 | 
			
		||||
			<arg line="grammar/LuaParser.jj"/>
 | 
			
		||||
		</java>
 | 
			
		||||
	</target>
 | 
			
		||||
		
 | 
			
		||||
	<target name="compile" depends="wtk-libs,bcel-lib">
 | 
			
		||||
		<delete dir="build/jme/src"/>
 | 
			
		||||
		<delete dir="build/jse/src"/>
 | 
			
		||||
		<mkdir dir="build/jme/src"/>
 | 
			
		||||
		<mkdir dir="build/jse/src"/>
 | 
			
		||||
		<mkdir dir="build/jme/classes"/>
 | 
			
		||||
		<mkdir dir="build/jse/classes"/>
 | 
			
		||||
		<copy todir="build/jme/src">
 | 
			
		||||
			<fileset dir="src/core"/>
 | 
			
		||||
			<fileset dir="src/jme"/>
 | 
			
		||||
			<filterchain>
 | 
			
		||||
				<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-jme ${version}"'/></tokenfilter>
 | 
			
		||||
			</filterchain>
 | 
			
		||||
		</copy>
 | 
			
		||||
		<copy todir="build/jse/src">
 | 
			
		||||
			<fileset dir="src/core"/>
 | 
			
		||||
			<filterchain>
 | 
			
		||||
				<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-jse ${version}"'/></tokenfilter>
 | 
			
		||||
			</filterchain>
 | 
			
		||||
		</copy>
 | 
			
		||||
		<copy todir="build/jse/src">
 | 
			
		||||
			<fileset dir="src/jse"/>
 | 
			
		||||
			<filterchain>
 | 
			
		||||
				<tokenfilter><replacestring from='<String>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<Stat>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<Exp>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<Name>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<Block>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<TableField>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<VarExp>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<Exp.VarExp>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<Object,String>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<Double,String>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<Integer,Integer>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<Exp,Integer>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<String,byte[]>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<String,Variable>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<LuaValue,String>' to=''/></tokenfilter>
 | 
			
		||||
				<tokenfilter><replacestring from='<LuaString,String>' to=''/></tokenfilter>
 | 
			
		||||
			</filterchain>
 | 
			
		||||
		</copy>
 | 
			
		||||
		<path id="wtk-libs">
 | 
			
		||||
			<pathelement path="lib/cldcapi11.jar"/>
 | 
			
		||||
			<pathelement path="lib/midpapi20.jar"/>
 | 
			
		||||
			<pathelement path="lib/mmapi.jar"/>
 | 
			
		||||
		</path>
 | 
			
		||||
		<javac destdir="build/jme/classes" encoding="utf-8" source="1.3" target="1.2" bootclasspathref="wtk-libs"
 | 
			
		||||
			srcdir="build/jme/src"/>
 | 
			
		||||
		<javac destdir="build/jse/classes" encoding="utf-8" source="1.3" target="1.3"
 | 
			
		||||
			classpath="lib/bcel-5.2.jar"
 | 
			
		||||
			srcdir="build/jse/src"
 | 
			
		||||
			excludes="**/script/*,**/Lua2Java*,lua*"/>
 | 
			
		||||
		<javac destdir="build/jse/classes" encoding="utf-8" source="1.5" target="1.5"
 | 
			
		||||
			classpath="build/jse/classes"
 | 
			
		||||
			srcdir="build/jse/src"
 | 
			
		||||
			includes="**/script/*,**/Lua2Java*"/>
 | 
			
		||||
		<javac destdir="build/jse/classes" encoding="utf-8" source="1.3" target="1.3"
 | 
			
		||||
			classpath="build/jse/classes"
 | 
			
		||||
			srcdir="build/jse/src"
 | 
			
		||||
			includes="lua*"/>
 | 
			
		||||
	</target>
 | 
			
		||||
	
 | 
			
		||||
	<target name="jar-jme" depends="compile">
 | 
			
		||||
		<jar destfile="${jar.name.jme}" basedir="build/jme/classes"/>
 | 
			
		||||
	</target>
 | 
			
		||||
	
 | 
			
		||||
	<target name="jar-jse" depends="compile">
 | 
			
		||||
		<jar destfile="${jar.name.jse}">
 | 
			
		||||
		    <fileset dir="build/jse/classes"/>
 | 
			
		||||
		    <fileset dir="src/jse/">
 | 
			
		||||
				<include name="META-INF/services/**"/>
 | 
			
		||||
		    </fileset>
 | 
			
		||||
		</jar>
 | 
			
		||||
	</target>
 | 
			
		||||
 | 
			
		||||
	<target name="jar-jse-sources" depends="compile">
 | 
			
		||||
		<jar destfile="${jar.name.sources}">
 | 
			
		||||
		    <fileset dir="build/jme/src"/>
 | 
			
		||||
		    <fileset dir="build/jse/src"/>
 | 
			
		||||
		</jar>
 | 
			
		||||
	</target>
 | 
			
		||||
 | 
			
		||||
	<target name="doc">
 | 
			
		||||
		<delete dir="docs/api"/>
 | 
			
		||||
		<mkdir dir="docs/api"/>
 | 
			
		||||
		<javadoc defaultexcludes="yes"
 | 
			
		||||
				destdir="docs/api"
 | 
			
		||||
				author="true"
 | 
			
		||||
				version="true"
 | 
			
		||||
				use="true"
 | 
			
		||||
				windowtitle="Luaj API">
 | 
			
		||||
		    <fileset dir="src/core" defaultexcludes="yes" includes="org/luaj/vm2/*.java,org/luaj/vm2/compiler/LuaC.java,org/luaj/vm2/lib/*.java"/>
 | 
			
		||||
		    <fileset dir="src/jse" defaultexcludes="yes" includes="org/luaj/vm2/lib/jse/*.java,org/luaj/vm2/luajc/LuaJC.java"/>
 | 
			
		||||
		    <fileset dir="src/jme" defaultexcludes="yes" includes="org/luaj/vm2/lib/jme/*.java"/>
 | 
			
		||||
			<doctitle><![CDATA[<h1>Luaj API</h1>]]></doctitle>
 | 
			
		||||
			<bottom><![CDATA[<i>Copyright © 2007-2008 Luaj.org. All Rights Reserved.</i>]]></bottom>
 | 
			
		||||
			<tag name="todo" scope="all" description="To do:"/>
 | 
			
		||||
			<group title="Core VM" packages="org.luaj.vm.*"/>
 | 
			
		||||
			<link offline="true" href="http://sourceforge.net/projects/luaj/" packagelistLoc="C:\tmp"/>
 | 
			
		||||
			<link href="http://sourceforge.net/projects/luaj/"/>
 | 
			
		||||
		</javadoc>
 | 
			
		||||
	</target>
 | 
			
		||||
	
 | 
			
		||||
	<target name="dist" depends="all,doc">
 | 
			
		||||
		<delete dir="build/luaj-${version}"/>
 | 
			
		||||
		<mkdir dir="build/luaj-${version}/src"/>
 | 
			
		||||
		<mkdir dir="build/luaj-${version}/lib"/>
 | 
			
		||||
		<copy todir="build/luaj-${version}/src">
 | 
			
		||||
		    <fileset dir="src">
 | 
			
		||||
				<exclude name="src/test/**"/>
 | 
			
		||||
				<exclude name="**/antlr/**"/>
 | 
			
		||||
				<exclude name="**/lst/**"/>
 | 
			
		||||
				<exclude name="**/JavaCodeGenerator.java"/>
 | 
			
		||||
				<exclude name="**/LuaJCompiler.java"/>
 | 
			
		||||
		    </fileset>
 | 
			
		||||
		</copy>
 | 
			
		||||
		<copy todir="build/luaj-${version}/test">
 | 
			
		||||
		    <fileset dir="test"/>
 | 
			
		||||
		</copy>
 | 
			
		||||
		<copy todir="build/luaj-${version}/examples">
 | 
			
		||||
		    <fileset dir="examples"/>
 | 
			
		||||
		</copy>
 | 
			
		||||
		<copy todir="build/luaj-${version}/lib">
 | 
			
		||||
		    <fileset dir=".">
 | 
			
		||||
				<include name="*-${version}.jar"/>
 | 
			
		||||
		    </fileset>		
 | 
			
		||||
		</copy>
 | 
			
		||||
		<copy todir="build/luaj-${version}">
 | 
			
		||||
		    <fileset dir=".">
 | 
			
		||||
				<include name="build.xml"/>
 | 
			
		||||
				<include name="build-libs.xml"/>
 | 
			
		||||
				<include name="build-coverage.xml"/>
 | 
			
		||||
				<include name="version.properties"/>
 | 
			
		||||
				<include name="wtk.xml"/>
 | 
			
		||||
				<include name="README.html"/>
 | 
			
		||||
				<include name="names.csv"/>
 | 
			
		||||
				<include name=".classpath"/>
 | 
			
		||||
				<include name=".project"/>
 | 
			
		||||
		    </fileset>		
 | 
			
		||||
		</copy>
 | 
			
		||||
		<copy todir="build/luaj-${version}/docs">
 | 
			
		||||
			<fileset dir="docs"/>
 | 
			
		||||
		</copy>
 | 
			
		||||
		<zip destfile="luaj-${version}.zip" 
 | 
			
		||||
			basedir="build" includes="luaj-${version}/**"/>
 | 
			
		||||
	</target>
 | 
			
		||||
	
 | 
			
		||||
	<target name="all" depends="clean,jar-jme,jar-jse,jar-jse-sources"/>
 | 
			
		||||
		
 | 
			
		||||
</project>
 | 
			
		||||
@@ -1,89 +0,0 @@
 | 
			
		||||
LuaValue Consructors,,Return type,,,,,,,,,,
 | 
			
		||||
,valueOf(boolean),LuaBoolean,,,,,,,,,,
 | 
			
		||||
,valueOf(null),LuaNil,,,,,,,,,,
 | 
			
		||||
,valueOf(int) ,LuaInteger,,,,,,,,,,
 | 
			
		||||
,valueOf(double),LuaNumber,,,,,,,,,,
 | 
			
		||||
,valueOf(long),LuaNumber,,,,,,,,,,
 | 
			
		||||
,valueOf(String),LuaString,,,,,,,,,,
 | 
			
		||||
,tableOf(...),LuaTable,,,,,,,,,,
 | 
			
		||||
,listOf(LuaValue[]),LuaTable,,,,,,,,,,
 | 
			
		||||
,userdataOf(Object),LuaUserdata,,,,,,,,,,
 | 
			
		||||
,"uerdataOf(Object,Value)",LuaUserdata,,,,,,,,,,
 | 
			
		||||
,,,,,,,Arugment type,,,,,
 | 
			
		||||
,,,LuaBoolean,LuaClosure,LuaFunction,LuaDouble,LuaInteger,LuaNil,LuaString,LuaTable,LuaThread,LuaUserdata
 | 
			
		||||
Type Check Functions,,,,,,,,,,,,
 | 
			
		||||
,isboolean,boolean,TRUE,f,f,f,f,f,f,f,f,f
 | 
			
		||||
,isclosure,boolean,f,TRUE,f,f,f,f,f,f,f,f
 | 
			
		||||
,isfunction,boolean,f,TRUE,TRUE,f,f,f,f,f,f,f
 | 
			
		||||
,isint,boolean,f,f,f,f,TRUE,f,true | f,f,f,f
 | 
			
		||||
,isinttype,boolean,f,f,f,f,TRUE,f,f,f,f,f
 | 
			
		||||
,isnumber,boolean,f,f,f,TRUE,TRUE,f,true | f,f,f,f
 | 
			
		||||
,islong,boolean,f,f,f,true | f,TRUE,f,true | f,f,f,f
 | 
			
		||||
,isnil,boolean,f,f,f,f,f,TRUE,f,f,f,f
 | 
			
		||||
,isstring,boolean,f,f,f,true | f,TRUE,f,TRUE,f,f,f
 | 
			
		||||
,istable,boolean,f,f,f,f,f,f,f,TRUE,f,f
 | 
			
		||||
,isthread,boolean,f,f,f,f,f,f,f,f,TRUE,f
 | 
			
		||||
,isuserdata,boolean,f,f,f,f,f,f,f,f,f,TRUE
 | 
			
		||||
,isuserdata(Class c),boolean,f,f,f,f,f,f,f,f,f,true | f
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Java Type Coercion Functions,,,,,,,,,,,,
 | 
			
		||||
,toboolean,boolean,this.v,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE
 | 
			
		||||
,tobyte,byte,0,0,0,0,this.v | 0,0,this.v | 0,0,0,0
 | 
			
		||||
,tochar,char,0,0,0,0,this.v | 0,0,this.v | 0,0,0,0
 | 
			
		||||
,todouble,double,0,0,0,this.v,this.v,0,this.v | 0,0,0,0
 | 
			
		||||
,tofloat,float,0,0,0,this.v | 0,this.v,0,this.v | 0,0,0,0
 | 
			
		||||
,toint,int,0,0,0,0,this.v,0,this.v | 0,0,0,0
 | 
			
		||||
,tolong,long,0,0,0,0,this.v,0,this.v | 0,0,0,0
 | 
			
		||||
,toshort,short,0,0,0,0,this.v | 0,0,this.v | 0,0,0,0
 | 
			
		||||
,tojstring,String,"""true""|""false""","""closure: x""","""name""",(str) this.v,(str) this.v,"""nil""",this.v,"""table: x""","""thread: x""","""userdata: x"""
 | 
			
		||||
,touserdata,Object,null,null,null,null,null,null,null,null,this,this.instance
 | 
			
		||||
 | 
			
		||||
,,,LuaBoolean,LuaClosure,LuaFunction,LuaDouble,LuaInteger,LuaNil,LuaString,LuaTable,LuaThread,LuaUserdata
 | 
			
		||||
Optional Argument Conversion Functions,,,,,,,,,,,,
 | 
			
		||||
,optboolean,boolean,this,e,e,e,e,defval,e,e,e,e
 | 
			
		||||
,optclosure,LuaClosure,n,this,e,e,e,defval,e,e,e,e
 | 
			
		||||
,optdouble,double,e,e,e,this,this,defval,this | e,e,e,e
 | 
			
		||||
,optfunction,LuaFunction,n,this,this,e,e,defval,e,e,e,e
 | 
			
		||||
,optint,int,e,e,e,(int) this,this,defval,this | e,e,e,e
 | 
			
		||||
,optinteger,LuaInteger,e,e,e,(int) this,this,defval,this | e,e,e,e
 | 
			
		||||
,optlong,long,e,e,e,(long) this,this,defval,this | e,e,e,e
 | 
			
		||||
,optnumber,LuaNumber,e,e,e,this,this,defval,this | e,e,e,e
 | 
			
		||||
,optjstring,String,e,e,e,(str) this.v,(str) this.v,defval,this,e,e,e
 | 
			
		||||
,optstring,LuaString,e,e,e,(str) this.v,(str) this.v,defval,this,e,e,e
 | 
			
		||||
,opttable,LuaTable,e,e,e,e,e,defval,e,this,e,e
 | 
			
		||||
,optthread,LuaThread,e,e,e,e,e,defval,e,e,this,n
 | 
			
		||||
,optuserdata,Object,e,e,e,e,e,defval,e,e,e,instance
 | 
			
		||||
,optuserdata(Class c),Object,e,e,e,e,e,defval,e,e,e,instance | e
 | 
			
		||||
 | 
			
		||||
Required Argument Conversion Functions,,,,,,,,,,,,
 | 
			
		||||
,checkboolean,boolean,this,e,e,e,e,e,e,e,e,e
 | 
			
		||||
,checkclosure,LuaClosure,e,this,e,e,e,e,e,e,e,e
 | 
			
		||||
,checkdouble,double,e,e,e,this,this,e,e,e,e,e
 | 
			
		||||
,checkfunction,LuaFunction,e,this,this,e,e,e,e,e,e,e
 | 
			
		||||
,checkint,int,e,e,e,this | e,this,e,e,e,e,e
 | 
			
		||||
,checkinteger,LuaInteger,e,e,e,e,this,e,e,e,e,e
 | 
			
		||||
,checklong,LuaNumber,e,e,e,this | e,this,e,e,e,e,e
 | 
			
		||||
,checknumber,LuaNumber,e,e,e,this,this,e,e,e,e,e
 | 
			
		||||
,checkjstring,String,e,e,e,(str) this.v,(str) this.v,e,(str) this.v,e,e,e
 | 
			
		||||
,checkstring,LuaString,e,e,e,(str) this.v,(str) this.v,e,this,e,e,e
 | 
			
		||||
,checktable,LuaTable,e,e,e,e,e,e,e,this,e,e
 | 
			
		||||
,checkthread,LuaThread,e,e,e,e,e,e,e,e,this,e
 | 
			
		||||
,checkuserdata,Object,e,e,e,e,e,e,e,e,e,instance
 | 
			
		||||
,checkuserdata(Class c),Object,e,e,e,e,e,e,e,e,e,instance | e
 | 
			
		||||
,checkvalue,LuaValue,this,this,this,this,this,e,this,this,this,this
 | 
			
		||||
 | 
			
		||||
,,,LuaBoolean,LuaClosure,LuaFunction,LuaDouble,LuaInteger,LuaNil,LuaString,LuaTable,LuaThread,LuaUserdata
 | 
			
		||||
Lua Language Operations,,,,,,,,,,,,
 | 
			
		||||
,type,int,TBOOLEAN,TFUNCTION,TFUNCTION,TNUMBER,TNUMBER,TNIL,TSTRING,TTABLE,TTHREAD,TUSERDATA
 | 
			
		||||
,typename,string,"""boolean""","""function""","""function""","""number""","""number""","""nil""","""string""","""table""","""thread""","""userdata"""
 | 
			
		||||
,len,LuaInteger,e,e,e,e,e,e,#v,#v,e,e
 | 
			
		||||
,length,int,e,e,e,e,e,e,#v,#v,e,e
 | 
			
		||||
,getmetatable,LuaValue,static,static,static,static,static,static,static,instance,static ,instance
 | 
			
		||||
,setmetatable,LuaValue,e,e,e,e,e,e,e,instance,e,instance
 | 
			
		||||
,getfenv,LuaTable,e,instance,instance,e,e,e,e,e,instance,e
 | 
			
		||||
,setfenv,LuaFunction,e,instance,instance,e,e,e,e,e,instance,e
 | 
			
		||||
,call,LuaValue,__call,call,call,__call,__call,__call,__call,__call,__call,__call
 | 
			
		||||
,invoke,Varargs,__call,call,call,__call,__call,__call,__call,__call,__call,__call
 | 
			
		||||
,get,LuaValue,__index,__index,__index,__index,__index,__index,__index,get,__index,__index
 | 
			
		||||
,set,LuaValue,__newindex,__newindex,__newindex,__newindex,__newindex,__newindex,__newindex,set,__newindex,__newindex
 | 
			
		||||
		
		
			
  | 
@@ -1,260 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * String buffer for use in string library methods, optimized for production 
 | 
			
		||||
 * of StrValue instances.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The buffer can begin initially as a wrapped {@link LuaValue} 
 | 
			
		||||
 * and only when concatenation actually occurs are the bytes first copied.
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * To convert back to a {@link LuaValue} again, 
 | 
			
		||||
 * the function {@link Buffer#value()} is used.
 | 
			
		||||
 * @see LuaValue
 | 
			
		||||
 * @see LuaValue#buffer()
 | 
			
		||||
 * @see LuaString
 | 
			
		||||
 */
 | 
			
		||||
public final class Buffer {
 | 
			
		||||
	
 | 
			
		||||
	/** Default capacity for a buffer: 64 */
 | 
			
		||||
	private static final int DEFAULT_CAPACITY = 64;
 | 
			
		||||
	
 | 
			
		||||
	/** Shared static array with no bytes */
 | 
			
		||||
	private static final byte[] NOBYTES = {};
 | 
			
		||||
 | 
			
		||||
	/** Bytes in this buffer */
 | 
			
		||||
	private byte[] bytes;
 | 
			
		||||
	
 | 
			
		||||
	/** Length of this buffer */
 | 
			
		||||
	private int length;
 | 
			
		||||
	
 | 
			
		||||
	/** Offset into the byte array */
 | 
			
		||||
	private int offset;
 | 
			
		||||
	
 | 
			
		||||
	/** Value of this buffer, when not represented in bytes */
 | 
			
		||||
	private LuaValue value;
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create buffer with default capacity
 | 
			
		||||
	 * @see #DEFAULT_CAPACITY
 | 
			
		||||
	 */
 | 
			
		||||
	public Buffer() {
 | 
			
		||||
		this(DEFAULT_CAPACITY);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create buffer with specified initial capacity
 | 
			
		||||
	 * @param initialCapacity the initial capacity
 | 
			
		||||
	 */
 | 
			
		||||
	public Buffer( int initialCapacity ) {
 | 
			
		||||
		bytes = new byte[ initialCapacity ];
 | 
			
		||||
		length = 0;
 | 
			
		||||
		offset = 0;
 | 
			
		||||
		value = null;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create buffer with specified initial value
 | 
			
		||||
	 * @param value the initial value
 | 
			
		||||
	 */
 | 
			
		||||
	public Buffer(LuaValue value) {
 | 
			
		||||
		bytes = NOBYTES;
 | 
			
		||||
		length = offset = 0;
 | 
			
		||||
		this.value = value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Get buffer contents as a {@link LuaValue}
 | 
			
		||||
	 * @return value as a {@link LuaValue}, converting as necessary
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaValue value() {
 | 
			
		||||
		return value != null? value: this.tostring();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Set buffer contents as a {@link LuaValue}
 | 
			
		||||
	 * @param value value to set
 | 
			
		||||
	 */
 | 
			
		||||
	public Buffer setvalue(LuaValue value) {
 | 
			
		||||
		bytes = NOBYTES;
 | 
			
		||||
		offset = length = 0;
 | 
			
		||||
		this.value = value;
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Convert the buffer to a {@link LuaString}
 | 
			
		||||
	 * @return the value as a {@link LuaString}
 | 
			
		||||
	 */
 | 
			
		||||
	public final LuaString tostring() {
 | 
			
		||||
		realloc( length, 0 );
 | 
			
		||||
		return LuaString.valueOf( bytes, offset, length );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Convert the buffer to a Java String
 | 
			
		||||
	 * @return the value as a Java String
 | 
			
		||||
	 */
 | 
			
		||||
	public String tojstring() {
 | 
			
		||||
		return value().tojstring();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Convert the buffer to a Java String
 | 
			
		||||
	 * @return the value as a Java String
 | 
			
		||||
	 */
 | 
			
		||||
	public String toString() {
 | 
			
		||||
		return tojstring();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Append a single byte to the buffer.
 | 
			
		||||
	 * @return {@code this} to allow call chaining
 | 
			
		||||
	 */
 | 
			
		||||
	public final Buffer append( byte b ) {
 | 
			
		||||
		makeroom( 0, 1 );
 | 
			
		||||
		bytes[ offset + length++ ] = b;
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Append a {@link LuaValue} to the buffer.
 | 
			
		||||
	 * @return {@code this} to allow call chaining
 | 
			
		||||
	 */
 | 
			
		||||
	public final Buffer append( LuaValue val ) {
 | 
			
		||||
		append( val.strvalue() );
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Append a {@link LuaString} to the buffer.
 | 
			
		||||
	 * @return {@code this} to allow call chaining
 | 
			
		||||
	 */
 | 
			
		||||
	public final Buffer append( LuaString str ) {
 | 
			
		||||
		final int n = str.m_length;
 | 
			
		||||
		makeroom( 0, n );
 | 
			
		||||
		str.copyInto( 0, bytes, offset + length, n );
 | 
			
		||||
		length += n;
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Append a Java String to the buffer.
 | 
			
		||||
	 * The Java string will be converted to bytes using the UTF8 encoding. 
 | 
			
		||||
	 * @return {@code this} to allow call chaining
 | 
			
		||||
	 * @see LuaString#encodeToUtf8(char[], byte[], int)
 | 
			
		||||
	 */
 | 
			
		||||
	public final Buffer append( String str ) {
 | 
			
		||||
		char[] chars = str.toCharArray();
 | 
			
		||||
		/* DAN200 START */
 | 
			
		||||
		/*
 | 
			
		||||
		final int n = LuaString.lengthAsUtf8( chars );
 | 
			
		||||
		makeroom( 0, n );
 | 
			
		||||
		LuaString.encodeToUtf8( chars, bytes, offset + length );
 | 
			
		||||
		length += n;
 | 
			
		||||
		*/
 | 
			
		||||
		makeroom( 0, chars.length );
 | 
			
		||||
		for( int i=0; i<chars.length; ++i )
 | 
			
		||||
		{
 | 
			
		||||
			char ch = chars[i];
 | 
			
		||||
			bytes[ offset + length + i ] = (ch < 256) ? (byte)ch : (byte)'?';
 | 
			
		||||
		}
 | 
			
		||||
		length += chars.length;
 | 
			
		||||
		/* DAN200 END */
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Concatenate this buffer onto a {@link LuaValue}
 | 
			
		||||
	 * @param lhs the left-hand-side value onto which we are concatenating {@code this} 
 | 
			
		||||
	 * @return {@link Buffer} for use in call chaining.
 | 
			
		||||
	 */
 | 
			
		||||
	public Buffer concatTo(LuaValue lhs) {
 | 
			
		||||
		return setvalue(lhs.concat(value()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Concatenate this buffer onto a {@link LuaString}
 | 
			
		||||
	 * @param lhs the left-hand-side value onto which we are concatenating {@code this} 
 | 
			
		||||
	 * @return {@link Buffer} for use in call chaining.
 | 
			
		||||
	 */
 | 
			
		||||
	public Buffer concatTo(LuaString lhs) {
 | 
			
		||||
		return value!=null&&!value.isstring()? setvalue(lhs.concat(value)): prepend(lhs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Concatenate this buffer onto a {@link LuaNumber}
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * The {@link LuaNumber} will be converted to a string before concatenating. 
 | 
			
		||||
	 * @param lhs the left-hand-side value onto which we are concatenating {@code this} 
 | 
			
		||||
	 * @return {@link Buffer} for use in call chaining.
 | 
			
		||||
	 */
 | 
			
		||||
	public Buffer concatTo(LuaNumber lhs) {
 | 
			
		||||
		return value!=null&&!value.isstring()? setvalue(lhs.concat(value)): prepend(lhs.strvalue());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Concatenate bytes from a {@link LuaString} onto the front of this buffer
 | 
			
		||||
	 * @param s the left-hand-side value which we will concatenate onto the front of {@code this} 
 | 
			
		||||
	 * @return {@link Buffer} for use in call chaining.
 | 
			
		||||
	 */
 | 
			
		||||
	public Buffer prepend(LuaString s) {
 | 
			
		||||
		int n = s.m_length;
 | 
			
		||||
		makeroom( n, 0 );
 | 
			
		||||
		System.arraycopy( s.m_bytes, s.m_offset, bytes, offset-n, n );
 | 
			
		||||
		offset -= n;
 | 
			
		||||
		length += n;
 | 
			
		||||
		value = null;
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Ensure there is enough room before and after the bytes.
 | 
			
		||||
	 * @param nbefore number of unused bytes which must precede the data after this completes 
 | 
			
		||||
	 * @param nafter number of unused bytes which must follow the data after this completes 
 | 
			
		||||
	 */
 | 
			
		||||
	public final void makeroom( int nbefore, int nafter ) {
 | 
			
		||||
		if ( value != null ) {
 | 
			
		||||
			LuaString s = value.strvalue();
 | 
			
		||||
			value = null;
 | 
			
		||||
			length = s.m_length;
 | 
			
		||||
			offset = nbefore;
 | 
			
		||||
			bytes = new byte[nbefore+length+nafter];
 | 
			
		||||
			System.arraycopy(s.m_bytes, s.m_offset, bytes, offset, length);
 | 
			
		||||
		} else if ( offset+length+nafter > bytes.length || offset<nbefore ) {
 | 
			
		||||
			int n = nbefore+length+nafter;
 | 
			
		||||
			int m = n<32? 32: n<length*2? length*2: n;
 | 
			
		||||
			realloc( m, nbefore==0? 0: m-length-nafter );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Reallocate the internal storage for the buffer
 | 
			
		||||
	 * @param newSize the size of the buffer to use 
 | 
			
		||||
	 * @param newOffset the offset to use 
 | 
			
		||||
	 */
 | 
			
		||||
	private final void realloc( int newSize, int newOffset ) {
 | 
			
		||||
		if ( newSize != bytes.length ) {
 | 
			
		||||
			byte[] newBytes = new byte[ newSize ];
 | 
			
		||||
			System.arraycopy( bytes, offset, newBytes, newOffset, length );
 | 
			
		||||
			bytes = newBytes;
 | 
			
		||||
			offset = newOffset;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,428 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
import java.io.DataInputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* Class to manage loading of {@link Prototype} instances.
 | 
			
		||||
* <p>
 | 
			
		||||
* The {@link LoadState} class exposes one main function, 
 | 
			
		||||
* namely {@link #load(InputStream, String, LuaValue)}, 
 | 
			
		||||
* to be used to load code from a particular input stream.  
 | 
			
		||||
* <p>
 | 
			
		||||
* A simple pattern for loading and executing code is
 | 
			
		||||
* <pre> {@code
 | 
			
		||||
* LuaValue _G = JsePlatform.standardGlobals();
 | 
			
		||||
* LoadState.load( new FileInputStream("main.lua"), "main.lua", _G ).call();
 | 
			
		||||
* } </pre>
 | 
			
		||||
* This should work regardless of which {@link LuaCompiler}
 | 
			
		||||
* has been installed.
 | 
			
		||||
* <p>
 | 
			
		||||
*  
 | 
			
		||||
* Prior to loading code, a compiler should be installed. 
 | 
			
		||||
* <p>
 | 
			
		||||
* By default, when using {@link JsePlatform} or {@JmePlatform}
 | 
			
		||||
* to construct globals, the {@link LuaC} compiler is installed. 
 | 
			
		||||
* <p>
 | 
			
		||||
* To override the default compiler with, say, the {@link LuaJC}
 | 
			
		||||
* lua-to-java bytecode compiler, install it before loading, 
 | 
			
		||||
* for example:
 | 
			
		||||
* <pre> {@code
 | 
			
		||||
* LuaValue _G = JsePlatform.standardGlobals();
 | 
			
		||||
* LuaJC.install();
 | 
			
		||||
* LoadState.load( new FileInputStream("main.lua"), "main.lua", _G ).call();
 | 
			
		||||
* } </pre>
 | 
			
		||||
* 
 | 
			
		||||
* @see LuaCompiler
 | 
			
		||||
* @see LuaClosure
 | 
			
		||||
* @see LuaFunction
 | 
			
		||||
* @see LoadState#compiler
 | 
			
		||||
* @see LoadState#load(InputStream, String, LuaValue)
 | 
			
		||||
* @see LuaC
 | 
			
		||||
* @see LuaJC
 | 
			
		||||
*/
 | 
			
		||||
public class LoadState {
 | 
			
		||||
	
 | 
			
		||||
	/** format corresponding to non-number-patched lua, all numbers are floats or doubles */
 | 
			
		||||
	public static final int NUMBER_FORMAT_FLOATS_OR_DOUBLES    = 0;
 | 
			
		||||
 | 
			
		||||
	/** format corresponding to non-number-patched lua, all numbers are ints */
 | 
			
		||||
	public static final int NUMBER_FORMAT_INTS_ONLY            = 1;
 | 
			
		||||
	
 | 
			
		||||
	/** format corresponding to number-patched lua, all numbers are 32-bit (4 byte) ints */
 | 
			
		||||
	public static final int NUMBER_FORMAT_NUM_PATCH_INT32      = 4;
 | 
			
		||||
	
 | 
			
		||||
	// type constants	
 | 
			
		||||
	public static final int LUA_TINT            = (-2);
 | 
			
		||||
	public static final int LUA_TNONE			= (-1);
 | 
			
		||||
	public static final int LUA_TNIL			= 0;
 | 
			
		||||
	public static final int LUA_TBOOLEAN		= 1;
 | 
			
		||||
	public static final int LUA_TLIGHTUSERDATA	= 2;
 | 
			
		||||
	public static final int LUA_TNUMBER			= 3;
 | 
			
		||||
	public static final int LUA_TSTRING			= 4;
 | 
			
		||||
	public static final int LUA_TTABLE			= 5;
 | 
			
		||||
	public static final int LUA_TFUNCTION		= 6;
 | 
			
		||||
	public static final int LUA_TUSERDATA		= 7;
 | 
			
		||||
	public static final int LUA_TTHREAD			= 8;
 | 
			
		||||
	public static final int LUA_TVALUE          = 9;
 | 
			
		||||
	
 | 
			
		||||
	/** Interface for the compiler, if it is installed. 
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * See the {@link LuaClosure} documentation for examples of how to use the compiler. 
 | 
			
		||||
	 * @see LuaClosure
 | 
			
		||||
	 * @see #load(InputStream, String, LuaValue)
 | 
			
		||||
	 * */
 | 
			
		||||
	public interface LuaCompiler {
 | 
			
		||||
		
 | 
			
		||||
		/** Load into a Closure or LuaFunction from a Stream and initializes the environment 
 | 
			
		||||
		 * @throws IOException */
 | 
			
		||||
		public LuaFunction load(InputStream stream, String filename, LuaValue env) throws IOException;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Compiler instance, if installed */
 | 
			
		||||
	public static LuaCompiler compiler = null;
 | 
			
		||||
 | 
			
		||||
	/** Signature byte indicating the file is a compiled binary chunk */
 | 
			
		||||
	private static final byte[] LUA_SIGNATURE	= { '\033', 'L', 'u', 'a' };
 | 
			
		||||
 | 
			
		||||
	/** Name for compiled chunks */
 | 
			
		||||
	public static final String SOURCE_BINARY_STRING = "binary string";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/** for header of binary files -- this is Lua 5.1 */
 | 
			
		||||
	public static final int LUAC_VERSION		= 0x51;
 | 
			
		||||
 | 
			
		||||
	/** for header of binary files -- this is the official format */
 | 
			
		||||
	public static final int LUAC_FORMAT		= 0;
 | 
			
		||||
 | 
			
		||||
	/** size of header of binary files */
 | 
			
		||||
	public static final int LUAC_HEADERSIZE		= 12;
 | 
			
		||||
 | 
			
		||||
	// values read from the header
 | 
			
		||||
	private int     luacVersion;
 | 
			
		||||
	private int     luacFormat;
 | 
			
		||||
	private boolean luacLittleEndian;
 | 
			
		||||
	private int     luacSizeofInt;
 | 
			
		||||
	private int     luacSizeofSizeT;
 | 
			
		||||
	private int     luacSizeofInstruction;
 | 
			
		||||
	private int     luacSizeofLuaNumber;
 | 
			
		||||
	private int 	luacNumberFormat;
 | 
			
		||||
 | 
			
		||||
	/** input stream from which we are loading */
 | 
			
		||||
	public final DataInputStream is;
 | 
			
		||||
 | 
			
		||||
	/** Name of what is being loaded? */
 | 
			
		||||
	String name;
 | 
			
		||||
 | 
			
		||||
	private static final LuaValue[]     NOVALUES    = {};
 | 
			
		||||
	private static final Prototype[] NOPROTOS    = {};
 | 
			
		||||
	private static final LocVars[]   NOLOCVARS   = {};
 | 
			
		||||
	private static final LuaString[]  NOSTRVALUES = {};
 | 
			
		||||
	private static final int[]       NOINTS      = {};
 | 
			
		||||
	
 | 
			
		||||
	/** Read buffer */
 | 
			
		||||
	private byte[] buf = new byte[512];
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	/** Load a 4-byte int value from the input stream
 | 
			
		||||
	 * @return the int value laoded.  
 | 
			
		||||
	 **/
 | 
			
		||||
	int loadInt() throws IOException {
 | 
			
		||||
		is.readFully(buf,0,4);
 | 
			
		||||
		return luacLittleEndian? 
 | 
			
		||||
				(buf[3] << 24) | ((0xff & buf[2]) << 16) | ((0xff & buf[1]) << 8) | (0xff & buf[0]):
 | 
			
		||||
				(buf[0] << 24) | ((0xff & buf[1]) << 16) | ((0xff & buf[2]) << 8) | (0xff & buf[3]);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Load an array of int values from the input stream
 | 
			
		||||
	 * @return the array of int values laoded.  
 | 
			
		||||
	 **/
 | 
			
		||||
	int[] loadIntArray() throws IOException {
 | 
			
		||||
		int n = loadInt();
 | 
			
		||||
		if ( n == 0 )
 | 
			
		||||
			return NOINTS;
 | 
			
		||||
		
 | 
			
		||||
		// read all data at once
 | 
			
		||||
		int m = n << 2;
 | 
			
		||||
		if ( buf.length < m )
 | 
			
		||||
			buf = new byte[m];
 | 
			
		||||
		is.readFully(buf,0,m);
 | 
			
		||||
		int[] array = new int[n];
 | 
			
		||||
		for ( int i=0, j=0; i<n; ++i, j+=4 )
 | 
			
		||||
			array[i] = luacLittleEndian? 
 | 
			
		||||
					(buf[j+3] << 24) | ((0xff & buf[j+2]) << 16) | ((0xff & buf[j+1]) << 8) | (0xff & buf[j+0]):
 | 
			
		||||
					(buf[j+0] << 24) | ((0xff & buf[j+1]) << 16) | ((0xff & buf[j+2]) << 8) | (0xff & buf[j+3]);
 | 
			
		||||
 | 
			
		||||
		return array;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Load a long  value from the input stream
 | 
			
		||||
	 * @return the long value laoded.  
 | 
			
		||||
	 **/
 | 
			
		||||
	long loadInt64() throws IOException {
 | 
			
		||||
		int a,b;
 | 
			
		||||
		if ( this.luacLittleEndian ) {
 | 
			
		||||
			a = loadInt();
 | 
			
		||||
			b = loadInt();
 | 
			
		||||
		} else {
 | 
			
		||||
			b = loadInt();
 | 
			
		||||
			a = loadInt();
 | 
			
		||||
		}
 | 
			
		||||
		return (((long)b)<<32) | (((long)a)&0xffffffffL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Load a lua strin gvalue from the input stream
 | 
			
		||||
	 * @return the {@link LuaString} value laoded.  
 | 
			
		||||
	 **/
 | 
			
		||||
	LuaString loadString() throws IOException {
 | 
			
		||||
		int size = this.luacSizeofSizeT == 8? (int) loadInt64(): loadInt();
 | 
			
		||||
		if ( size == 0 )
 | 
			
		||||
			return null;
 | 
			
		||||
		byte[] bytes = new byte[size];
 | 
			
		||||
		is.readFully( bytes, 0, size );
 | 
			
		||||
		return LuaString.valueOf( bytes, 0, bytes.length - 1 );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Convert bits in a long value to a {@link LuaValue}. 
 | 
			
		||||
	 * @param bits long value containing the bits
 | 
			
		||||
	 * @return {@link LuaInteger} or {@link LuaDouble} whose value corresponds to the bits provided.
 | 
			
		||||
	 */
 | 
			
		||||
	public static LuaValue longBitsToLuaNumber( long bits ) {
 | 
			
		||||
		if ( ( bits & ( ( 1L << 63 ) - 1 ) ) == 0L ) {
 | 
			
		||||
			return LuaValue.ZERO;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		int e = (int)((bits >> 52) & 0x7ffL) - 1023;
 | 
			
		||||
		
 | 
			
		||||
		if ( e >= 0 && e < 31 ) {
 | 
			
		||||
			long f = bits & 0xFFFFFFFFFFFFFL;
 | 
			
		||||
			int shift = 52 - e;
 | 
			
		||||
			long intPrecMask = ( 1L << shift ) - 1;
 | 
			
		||||
			if ( ( f & intPrecMask ) == 0 ) {
 | 
			
		||||
				int intValue = (int)( f >> shift ) | ( 1 << e );
 | 
			
		||||
				return LuaInteger.valueOf( ( ( bits >> 63 ) != 0 ) ? -intValue : intValue );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		return LuaValue.valueOf( Double.longBitsToDouble(bits) );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Load a number from a binary chunk
 | 
			
		||||
	 * @return the {@link LuaValue} loaded
 | 
			
		||||
	 * @throws IOException if an i/o exception occurs
 | 
			
		||||
	 */
 | 
			
		||||
	LuaValue loadNumber() throws IOException {
 | 
			
		||||
		if ( luacNumberFormat == NUMBER_FORMAT_INTS_ONLY ) {
 | 
			
		||||
			return LuaInteger.valueOf( loadInt() );
 | 
			
		||||
		} else {
 | 
			
		||||
			return longBitsToLuaNumber( loadInt64() );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Load a list of constants from a binary chunk
 | 
			
		||||
	 * @param f the function prototype
 | 
			
		||||
	 * @throws IOException if an i/o exception occurs
 | 
			
		||||
	 */
 | 
			
		||||
	void loadConstants(Prototype f) throws IOException {
 | 
			
		||||
		int n = loadInt();
 | 
			
		||||
		LuaValue[] values = n>0? new LuaValue[n]: NOVALUES;
 | 
			
		||||
		for ( int i=0; i<n; i++ ) {
 | 
			
		||||
			switch ( is.readByte() ) {
 | 
			
		||||
			case LUA_TNIL:
 | 
			
		||||
				values[i] = LuaValue.NIL;
 | 
			
		||||
				break;
 | 
			
		||||
			case LUA_TBOOLEAN:
 | 
			
		||||
				values[i] = (0 != is.readUnsignedByte()? LuaValue.TRUE: LuaValue.FALSE);
 | 
			
		||||
				break;
 | 
			
		||||
			case LUA_TINT:
 | 
			
		||||
				values[i] = LuaInteger.valueOf( loadInt() );
 | 
			
		||||
				break;
 | 
			
		||||
			case LUA_TNUMBER:
 | 
			
		||||
				values[i] = loadNumber();
 | 
			
		||||
				break;
 | 
			
		||||
			case LUA_TSTRING:
 | 
			
		||||
				values[i] = loadString();
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				throw new IllegalStateException("bad constant");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		f.k = values;
 | 
			
		||||
		
 | 
			
		||||
		n = loadInt();
 | 
			
		||||
		Prototype[] protos = n>0? new Prototype[n]: NOPROTOS;
 | 
			
		||||
		for ( int i=0; i<n; i++ )
 | 
			
		||||
			protos[i] = loadFunction(f.source);
 | 
			
		||||
		f.p = protos;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Load the debug infor for a function prototype
 | 
			
		||||
	 * @param f the function Prototype
 | 
			
		||||
	 * @throws IOException if there is an i/o exception
 | 
			
		||||
	 */
 | 
			
		||||
	void loadDebug( Prototype f ) throws IOException {
 | 
			
		||||
		f.lineinfo = loadIntArray();
 | 
			
		||||
		int n = loadInt();
 | 
			
		||||
		f.locvars = n>0? new LocVars[n]: NOLOCVARS;
 | 
			
		||||
		for ( int i=0; i<n; i++ ) {
 | 
			
		||||
			LuaString varname = loadString();
 | 
			
		||||
			int startpc = loadInt();
 | 
			
		||||
			int endpc = loadInt();
 | 
			
		||||
			f.locvars[i] = new LocVars(varname, startpc, endpc);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		n = loadInt();
 | 
			
		||||
		f.upvalues = n>0? new LuaString[n]: NOSTRVALUES;
 | 
			
		||||
		for ( int i=0; i<n; i++ ) {
 | 
			
		||||
			f.upvalues[i] = loadString();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Load a function prototype from the input stream
 | 
			
		||||
	 * @param p name of the source
 | 
			
		||||
	 * @return {@link Prototype} instance that was loaded
 | 
			
		||||
	 * @throws IOException
 | 
			
		||||
	 */
 | 
			
		||||
	public Prototype loadFunction(LuaString p) throws IOException {
 | 
			
		||||
		Prototype f = new Prototype();
 | 
			
		||||
//		this.L.push(f);
 | 
			
		||||
		f.source = loadString();
 | 
			
		||||
		if ( f.source == null )
 | 
			
		||||
			f.source = p;
 | 
			
		||||
		f.linedefined = loadInt();
 | 
			
		||||
		f.lastlinedefined = loadInt();
 | 
			
		||||
		f.nups = is.readUnsignedByte();
 | 
			
		||||
		f.numparams = is.readUnsignedByte();
 | 
			
		||||
		f.is_vararg = is.readUnsignedByte();
 | 
			
		||||
		f.maxstacksize = is.readUnsignedByte();
 | 
			
		||||
		f.code = loadIntArray();
 | 
			
		||||
		loadConstants(f);
 | 
			
		||||
		loadDebug(f);
 | 
			
		||||
		
 | 
			
		||||
		// TODO: add check here, for debugging purposes, I believe
 | 
			
		||||
		// see ldebug.c
 | 
			
		||||
//		 IF (!luaG_checkcode(f), "bad code");
 | 
			
		||||
		
 | 
			
		||||
//		 this.L.pop();
 | 
			
		||||
		 return f;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Load the lua chunk header values. 
 | 
			
		||||
	 * @throws IOException if an i/o exception occurs. 
 | 
			
		||||
	 */
 | 
			
		||||
	public void loadHeader() throws IOException {
 | 
			
		||||
		luacVersion = is.readByte();
 | 
			
		||||
		luacFormat = is.readByte();
 | 
			
		||||
		luacLittleEndian = (0 != is.readByte());
 | 
			
		||||
		luacSizeofInt = is.readByte();
 | 
			
		||||
		luacSizeofSizeT = is.readByte();
 | 
			
		||||
		luacSizeofInstruction = is.readByte();
 | 
			
		||||
		luacSizeofLuaNumber = is.readByte();
 | 
			
		||||
		luacNumberFormat = is.readByte();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Load lua in either binary or text form from an input stream.
 | 
			
		||||
	 * @param firstByte the first byte of the input stream
 | 
			
		||||
	 * @param stream InputStream to read, after having read the first byte already
 | 
			
		||||
	 * @param name Name to apply to the loaded chunk
 | 
			
		||||
	 * @return {@link Prototype} that was loaded
 | 
			
		||||
	 * @throws IllegalArgumentException if the signature is bac
 | 
			
		||||
	 * @throws IOException if an IOException occurs
 | 
			
		||||
	 */
 | 
			
		||||
	public static LuaFunction load( InputStream stream, String name, LuaValue env ) throws IOException {
 | 
			
		||||
		if ( compiler != null )
 | 
			
		||||
			return compiler.load(stream, name, env);
 | 
			
		||||
		else {
 | 
			
		||||
			int firstByte = stream.read();
 | 
			
		||||
			if ( firstByte != LUA_SIGNATURE[0] )
 | 
			
		||||
				throw new LuaError("no compiler");
 | 
			
		||||
			Prototype p = loadBinaryChunk( firstByte, stream, name );
 | 
			
		||||
			return new LuaClosure( p, env );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Load lua thought to be a binary chunk from its first byte from an input stream.
 | 
			
		||||
	 * @param firstByte the first byte of the input stream
 | 
			
		||||
	 * @param stream InputStream to read, after having read the first byte already
 | 
			
		||||
	 * @param name Name to apply to the loaded chunk
 | 
			
		||||
	 * @return {@link Prototype} that was loaded
 | 
			
		||||
	 * @throws IllegalArgumentException if the signature is bac
 | 
			
		||||
	 * @throws IOException if an IOException occurs
 | 
			
		||||
	 */
 | 
			
		||||
	public static Prototype loadBinaryChunk( int firstByte, InputStream stream, String name ) throws IOException {
 | 
			
		||||
 | 
			
		||||
		// check rest of signature
 | 
			
		||||
		if ( firstByte != LUA_SIGNATURE[0] 
 | 
			
		||||
		   || stream.read() != LUA_SIGNATURE[1]
 | 
			
		||||
	       || stream.read() != LUA_SIGNATURE[2]
 | 
			
		||||
		   || stream.read() != LUA_SIGNATURE[3] )
 | 
			
		||||
			throw new IllegalArgumentException("bad signature");
 | 
			
		||||
		
 | 
			
		||||
		// load file as a compiled chunk
 | 
			
		||||
		String sname = getSourceName(name);
 | 
			
		||||
		LoadState s = new LoadState( stream, sname );
 | 
			
		||||
		s.loadHeader();
 | 
			
		||||
 | 
			
		||||
		// check format
 | 
			
		||||
		switch ( s.luacNumberFormat ) {
 | 
			
		||||
		case NUMBER_FORMAT_FLOATS_OR_DOUBLES:
 | 
			
		||||
		case NUMBER_FORMAT_INTS_ONLY:
 | 
			
		||||
		case NUMBER_FORMAT_NUM_PATCH_INT32:
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			throw new LuaError("unsupported int size");
 | 
			
		||||
		}
 | 
			
		||||
		return s.loadFunction( LuaString.valueOf(sname) );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Construct a source name from a supplied chunk name
 | 
			
		||||
	 * @param name String name that appears in the chunk
 | 
			
		||||
	 * @return source file name
 | 
			
		||||
	 */
 | 
			
		||||
    public static String getSourceName(String name) {
 | 
			
		||||
        String sname = name;
 | 
			
		||||
        if ( name.startsWith("@") || name.startsWith("=") )
 | 
			
		||||
			sname = name.substring(1);
 | 
			
		||||
		else if ( name.startsWith("\033") )
 | 
			
		||||
			sname = SOURCE_BINARY_STRING;
 | 
			
		||||
        return sname;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	/** Private constructor for create a load state */
 | 
			
		||||
	private LoadState( InputStream stream, String name ) {
 | 
			
		||||
		this.name = name;
 | 
			
		||||
		this.is = new DataInputStream( stream );
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,52 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Data class to hold debug information relatign to local variables for a {@link Prototype}
 | 
			
		||||
 */
 | 
			
		||||
public class LocVars {
 | 
			
		||||
	/** The local variable name */
 | 
			
		||||
	public LuaString varname;
 | 
			
		||||
	
 | 
			
		||||
	/** The instruction offset when the variable comes into scope */ 
 | 
			
		||||
	public int startpc;
 | 
			
		||||
	
 | 
			
		||||
	/** The instruction offset when the variable goes out of scope */ 
 | 
			
		||||
	public int endpc;
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Construct a LocVars instance. 
 | 
			
		||||
	 * @param varname The local variable name
 | 
			
		||||
	 * @param startpc The instruction offset when the variable comes into scope
 | 
			
		||||
	 * @param endpc The instruction offset when the variable goes out of scope
 | 
			
		||||
	 */
 | 
			
		||||
	public LocVars(LuaString varname, int startpc, int endpc) {
 | 
			
		||||
		this.varname = varname;
 | 
			
		||||
		this.startpc = startpc;
 | 
			
		||||
		this.endpc = endpc;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public String tojstring() {
 | 
			
		||||
		return varname+" "+startpc+"-"+endpc;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,337 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Constants for lua limits and opcodes. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This is a direct translation of C lua distribution header file constants
 | 
			
		||||
 * for bytecode creation and processing.  
 | 
			
		||||
 */
 | 
			
		||||
public class Lua {
 | 
			
		||||
	/** version is supplied by ant build task */
 | 
			
		||||
	public static final String _VERSION = "Luaj 0.0";
 | 
			
		||||
 | 
			
		||||
	/** use return values from previous op */
 | 
			
		||||
	public static final int LUA_MULTRET = -1;
 | 
			
		||||
 | 
			
		||||
	/** masks for new-style vararg */
 | 
			
		||||
	public static final int     VARARG_HASARG		= 1;
 | 
			
		||||
	public static final int     VARARG_ISVARARG	= 2;
 | 
			
		||||
	public static final int     VARARG_NEEDSARG	= 4;
 | 
			
		||||
	
 | 
			
		||||
	// from lopcodes.h
 | 
			
		||||
 | 
			
		||||
	/*===========================================================================
 | 
			
		||||
	  We assume that instructions are unsigned numbers.
 | 
			
		||||
	  All instructions have an opcode in the first 6 bits.
 | 
			
		||||
	  Instructions can have the following fields:
 | 
			
		||||
		`A' : 8 bits
 | 
			
		||||
		`B' : 9 bits
 | 
			
		||||
		`C' : 9 bits
 | 
			
		||||
		`Bx' : 18 bits (`B' and `C' together)
 | 
			
		||||
		`sBx' : signed Bx
 | 
			
		||||
 | 
			
		||||
	  A signed argument is represented in excess K; that is, the number
 | 
			
		||||
	  value is the unsigned value minus K. K is exactly the maximum value
 | 
			
		||||
	  for that argument (so that -max is represented by 0, and +max is
 | 
			
		||||
	  represented by 2*max), which is half the maximum for the corresponding
 | 
			
		||||
	  unsigned argument.
 | 
			
		||||
	===========================================================================*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* basic instruction format */
 | 
			
		||||
	public static final int	iABC = 0;
 | 
			
		||||
	public static final int	iABx = 1;
 | 
			
		||||
	public static final int	iAsBx = 2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	** size and position of opcode arguments.
 | 
			
		||||
	*/
 | 
			
		||||
	public static final int SIZE_C		= 9;
 | 
			
		||||
	public static final int SIZE_B		= 9;
 | 
			
		||||
	public static final int SIZE_Bx		= (SIZE_C + SIZE_B);
 | 
			
		||||
	public static final int SIZE_A		= 8;
 | 
			
		||||
 | 
			
		||||
	public static final int SIZE_OP		= 6;
 | 
			
		||||
 | 
			
		||||
	public static final int POS_OP		= 0;
 | 
			
		||||
	public static final int POS_A		= (POS_OP + SIZE_OP);
 | 
			
		||||
	public static final int POS_C		= (POS_A + SIZE_A);
 | 
			
		||||
	public static final int POS_B		= (POS_C + SIZE_C);
 | 
			
		||||
	public static final int POS_Bx		= POS_C;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public static final int MAX_OP          = ((1<<SIZE_OP)-1);
 | 
			
		||||
	public static final int MAXARG_A        = ((1<<SIZE_A)-1);
 | 
			
		||||
	public static final int MAXARG_B        = ((1<<SIZE_B)-1);
 | 
			
		||||
	public static final int MAXARG_C        = ((1<<SIZE_C)-1);
 | 
			
		||||
	public static final int MAXARG_Bx       = ((1<<SIZE_Bx)-1);
 | 
			
		||||
	public static final int MAXARG_sBx      = (MAXARG_Bx>>1);     	/* `sBx' is signed */
 | 
			
		||||
 | 
			
		||||
	public static final int MASK_OP = ((1<<SIZE_OP)-1)<<POS_OP; 
 | 
			
		||||
	public static final int MASK_A  = ((1<<SIZE_A)-1)<<POS_A; 
 | 
			
		||||
	public static final int MASK_B  = ((1<<SIZE_B)-1)<<POS_B; 
 | 
			
		||||
	public static final int MASK_C  = ((1<<SIZE_C)-1)<<POS_C; 
 | 
			
		||||
	public static final int MASK_Bx = ((1<<SIZE_Bx)-1)<<POS_Bx; 
 | 
			
		||||
 | 
			
		||||
	public static final int MASK_NOT_OP = ~MASK_OP; 
 | 
			
		||||
	public static final int MASK_NOT_A  = ~MASK_A; 
 | 
			
		||||
	public static final int MASK_NOT_B  = ~MASK_B; 
 | 
			
		||||
	public static final int MASK_NOT_C  = ~MASK_C; 
 | 
			
		||||
	public static final int MASK_NOT_Bx = ~MASK_Bx; 
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	** the following macros help to manipulate instructions
 | 
			
		||||
	*/
 | 
			
		||||
	public static int GET_OPCODE(int i) {
 | 
			
		||||
		return (i >> POS_OP) & MAX_OP;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static int GETARG_A(int i) {
 | 
			
		||||
		return (i >> POS_A) & MAXARG_A;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static int GETARG_B(int i) {
 | 
			
		||||
		return (i >> POS_B) & MAXARG_B;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static int GETARG_C(int i) {
 | 
			
		||||
		return (i >> POS_C) & MAXARG_C;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static int GETARG_Bx(int i) {
 | 
			
		||||
		return (i >> POS_Bx) & MAXARG_Bx;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static int GETARG_sBx(int i) {
 | 
			
		||||
		return ((i >> POS_Bx) & MAXARG_Bx) - MAXARG_sBx;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	** Macros to operate RK indices
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	/** this bit 1 means constant (0 means register) */
 | 
			
		||||
	public static final int BITRK		= (1 << (SIZE_B - 1));
 | 
			
		||||
 | 
			
		||||
	/** test whether value is a constant */
 | 
			
		||||
	public static boolean ISK(int x) {
 | 
			
		||||
		return 0 != ((x) & BITRK);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** gets the index of the constant */
 | 
			
		||||
	public static int INDEXK(int r) {
 | 
			
		||||
		return ((int)(r) & ~BITRK);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static final int MAXINDEXRK	= (BITRK - 1);
 | 
			
		||||
 | 
			
		||||
	/** code a constant index as a RK value */
 | 
			
		||||
	public static int RKASK(int x) {
 | 
			
		||||
		return ((x) | BITRK);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	** invalid register that fits in 8 bits
 | 
			
		||||
	*/
 | 
			
		||||
	public static final int  NO_REG		= MAXARG_A;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	** R(x) - register
 | 
			
		||||
	** Kst(x) - constant (in constant table)
 | 
			
		||||
	** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	** grep "ORDER OP" if you change these enums
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	/*----------------------------------------------------------------------
 | 
			
		||||
	name		args	description
 | 
			
		||||
	------------------------------------------------------------------------*/
 | 
			
		||||
	public static final int OP_MOVE = 0;/*	A B	R(A) := R(B)					*/
 | 
			
		||||
	public static final int OP_LOADK = 1;/*	A Bx	R(A) := Kst(Bx)					*/
 | 
			
		||||
	public static final int OP_LOADBOOL = 2;/*	A B C	R(A) := (Bool)B; if (C) pc++			*/
 | 
			
		||||
	public static final int OP_LOADNIL = 3; /*	A B	R(A) := ... := R(B) := nil			*/
 | 
			
		||||
	public static final int OP_GETUPVAL = 4; /*	A B	R(A) := UpValue[B]				*/
 | 
			
		||||
 | 
			
		||||
	public static final int OP_GETGLOBAL = 5; /*	A Bx	R(A) := Gbl[Kst(Bx)]				*/
 | 
			
		||||
	public static final int OP_GETTABLE = 6; /*	A B C	R(A) := R(B)[RK(C)]				*/
 | 
			
		||||
 | 
			
		||||
	public static final int OP_SETGLOBAL = 7; /*	A Bx	Gbl[Kst(Bx)] := R(A)				*/
 | 
			
		||||
	public static final int OP_SETUPVAL = 8; /*	A B	UpValue[B] := R(A)				*/
 | 
			
		||||
	public static final int OP_SETTABLE = 9; /*	A B C	R(A)[RK(B)] := RK(C)				*/
 | 
			
		||||
 | 
			
		||||
	public static final int OP_NEWTABLE = 10; /*	A B C	R(A) := {} (size = B,C)				*/
 | 
			
		||||
 | 
			
		||||
	public static final int OP_SELF = 11; /*	A B C	R(A+1) := R(B); R(A) := R(B)[RK(C)]		*/
 | 
			
		||||
 | 
			
		||||
	public static final int OP_ADD = 12; /*	A B C	R(A) := RK(B) + RK(C)				*/
 | 
			
		||||
	public static final int OP_SUB = 13; /*	A B C	R(A) := RK(B) - RK(C)				*/
 | 
			
		||||
	public static final int OP_MUL = 14; /*	A B C	R(A) := RK(B) * RK(C)				*/
 | 
			
		||||
	public static final int OP_DIV = 15; /*	A B C	R(A) := RK(B) / RK(C)				*/
 | 
			
		||||
	public static final int OP_MOD = 16; /*	A B C	R(A) := RK(B) % RK(C)				*/
 | 
			
		||||
	public static final int OP_POW = 17; /*	A B C	R(A) := RK(B) ^ RK(C)				*/
 | 
			
		||||
	public static final int OP_UNM = 18; /*	A B	R(A) := -R(B)					*/
 | 
			
		||||
	public static final int OP_NOT = 19; /*	A B	R(A) := not R(B)				*/
 | 
			
		||||
	public static final int OP_LEN = 20; /*	A B	R(A) := length of R(B)				*/
 | 
			
		||||
 | 
			
		||||
	public static final int OP_CONCAT = 21; /*	A B C	R(A) := R(B).. ... ..R(C)			*/
 | 
			
		||||
 | 
			
		||||
	public static final int OP_JMP = 22; /*	sBx	pc+=sBx					*/
 | 
			
		||||
 | 
			
		||||
	public static final int OP_EQ = 23; /*	A B C	if ((RK(B) == RK(C)) ~= A) then pc++		*/
 | 
			
		||||
	public static final int OP_LT = 24; /*	A B C	if ((RK(B) <  RK(C)) ~= A) then pc++  		*/
 | 
			
		||||
	public static final int OP_LE = 25; /*	A B C	if ((RK(B) <= RK(C)) ~= A) then pc++  		*/
 | 
			
		||||
 | 
			
		||||
	public static final int OP_TEST = 26; /*	A C	if not (R(A) <=> C) then pc++			*/ 
 | 
			
		||||
	public static final int OP_TESTSET = 27; /*	A B C	if (R(B) <=> C) then R(A) := R(B) else pc++	*/ 
 | 
			
		||||
 | 
			
		||||
	public static final int OP_CALL = 28; /*	A B C	R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
 | 
			
		||||
	public static final int OP_TAILCALL = 29; /*	A B C	return R(A)(R(A+1), ... ,R(A+B-1))		*/
 | 
			
		||||
	public static final int OP_RETURN = 30; /*	A B	return R(A), ... ,R(A+B-2)	(see note)	*/
 | 
			
		||||
 | 
			
		||||
	public static final int OP_FORLOOP = 31; /*	A sBx	R(A)+=R(A+2);
 | 
			
		||||
				if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
 | 
			
		||||
	public static final int OP_FORPREP = 32; /*	A sBx	R(A)-=R(A+2); pc+=sBx				*/
 | 
			
		||||
 | 
			
		||||
	public static final int OP_TFORLOOP = 33; /*	A C	R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); 
 | 
			
		||||
	                        if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++	*/ 
 | 
			
		||||
	public static final int OP_SETLIST = 34; /*	A B C	R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B	*/
 | 
			
		||||
 | 
			
		||||
	public static final int OP_CLOSE = 35; /*	A 	close all variables in the stack up to (>=) R(A)*/
 | 
			
		||||
	public static final int OP_CLOSURE = 36; /*	A Bx	R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))	*/
 | 
			
		||||
	public static final int OP_VARARG = 37; /*	A B	R(A), R(A+1), ..., R(A+B-1) = vararg		*/
 | 
			
		||||
	
 | 
			
		||||
	public static final int NUM_OPCODES	= OP_VARARG + 1;
 | 
			
		||||
 | 
			
		||||
	/* pseudo-opcodes used in parsing only.  */
 | 
			
		||||
	public static final int OP_GT  = 63; // > 
 | 
			
		||||
	public static final int OP_GE  = 62; // >=
 | 
			
		||||
	public static final int OP_NEQ = 61; // ~= 
 | 
			
		||||
	public static final int OP_AND = 60; // and 
 | 
			
		||||
	public static final int OP_OR  = 59; // or 
 | 
			
		||||
	
 | 
			
		||||
	/*===========================================================================
 | 
			
		||||
	  Notes:
 | 
			
		||||
	  (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
 | 
			
		||||
	      and can be 0: OP_CALL then sets `top' to last_result+1, so
 | 
			
		||||
	      next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
 | 
			
		||||
 | 
			
		||||
	  (*) In OP_VARARG, if (B == 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_SETLIST, if (B == 0) then B = `top';
 | 
			
		||||
	      if (C == 0) then next `instruction' is real C
 | 
			
		||||
 | 
			
		||||
	  (*) For comparisons, A specifies what condition the test should accept
 | 
			
		||||
	      (true or false).
 | 
			
		||||
 | 
			
		||||
	  (*) All `skips' (pc++) assume that next instruction is a jump
 | 
			
		||||
	===========================================================================*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	** masks for instruction properties. The format is:
 | 
			
		||||
	** bits 0-1: op mode
 | 
			
		||||
	** bits 2-3: C arg mode
 | 
			
		||||
	** bits 4-5: B arg mode
 | 
			
		||||
	** bit 6: instruction set register A
 | 
			
		||||
	** bit 7: operator is a test
 | 
			
		||||
	*/  
 | 
			
		||||
 | 
			
		||||
	  public static final int OpArgN = 0;  /* argument is not used */
 | 
			
		||||
	  public static final int OpArgU = 1;  /* argument is used */
 | 
			
		||||
	  public static final int OpArgR = 2;  /* argument is a register or a jump offset */
 | 
			
		||||
	  public static final int OpArgK = 3;  /* argument is a constant or register/constant */
 | 
			
		||||
 | 
			
		||||
	  public static final int[] luaP_opmodes = {
 | 
			
		||||
	  /*   T        A           B             C          mode		   opcode	*/
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC),		/* OP_MOVE */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx),		/* OP_LOADK */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC),		/* OP_LOADBOOL */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC),		/* OP_LOADNIL */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC),		/* OP_GETUPVAL */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx),		/* OP_GETGLOBAL */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgK<<2) | (iABC),		/* OP_GETTABLE */
 | 
			
		||||
		 (0<<7) | (0<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx),		/* OP_SETGLOBAL */
 | 
			
		||||
		 (0<<7) | (0<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC),		/* OP_SETUPVAL */
 | 
			
		||||
		 (0<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC),		/* OP_SETTABLE */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC),		/* OP_NEWTABLE */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgK<<2) | (iABC),		/* OP_SELF */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC),		/* OP_ADD */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC),		/* OP_SUB */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC),		/* OP_MUL */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC),		/* OP_DIV */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC),		/* OP_MOD */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC),		/* OP_POW */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC),		/* OP_UNM */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC),		/* OP_NOT */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC),		/* OP_LEN */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgR<<2) | (iABC),		/* OP_CONCAT */
 | 
			
		||||
		 (0<<7) | (0<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx),		/* OP_JMP */
 | 
			
		||||
		 (1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC),		/* OP_EQ */
 | 
			
		||||
		 (1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC),		/* OP_LT */
 | 
			
		||||
		 (1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC),		/* OP_LE */
 | 
			
		||||
		 (1<<7) | (1<<6) | (OpArgR<<4) | (OpArgU<<2) | (iABC),		/* OP_TEST */
 | 
			
		||||
		 (1<<7) | (1<<6) | (OpArgR<<4) | (OpArgU<<2) | (iABC),		/* OP_TESTSET */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC),		/* OP_CALL */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC),		/* OP_TAILCALL */
 | 
			
		||||
		 (0<<7) | (0<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC),		/* OP_RETURN */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx),		/* OP_FORLOOP */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx),		/* OP_FORPREP */
 | 
			
		||||
		 (1<<7) | (0<<6) | (OpArgN<<4) | (OpArgU<<2) | (iABC),		/* OP_TFORLOOP */
 | 
			
		||||
		 (0<<7) | (0<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC),		/* OP_SETLIST */
 | 
			
		||||
		 (0<<7) | (0<<6) | (OpArgN<<4) | (OpArgN<<2) | (iABC),		/* OP_CLOSE */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABx),		/* OP_CLOSURE */
 | 
			
		||||
		 (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC),		/* OP_VARARG */
 | 
			
		||||
	  };
 | 
			
		||||
 | 
			
		||||
	public static int getOpMode(int m) {
 | 
			
		||||
		return luaP_opmodes[m] & 3;
 | 
			
		||||
	}
 | 
			
		||||
	public static int getBMode(int m) {
 | 
			
		||||
		return (luaP_opmodes[m] >> 4) & 3;
 | 
			
		||||
	}
 | 
			
		||||
	public static int getCMode(int m) {
 | 
			
		||||
		return (luaP_opmodes[m] >> 2) & 3;
 | 
			
		||||
	}
 | 
			
		||||
	public static boolean testAMode(int m) {
 | 
			
		||||
		return 0 != (luaP_opmodes[m] & (1 << 6));
 | 
			
		||||
	}
 | 
			
		||||
	public static boolean testTMode(int m) {
 | 
			
		||||
		return 0 != (luaP_opmodes[m] & (1 << 7));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* number of list items to accumulate before a SETLIST instruction */
 | 
			
		||||
	public static final int LFIELDS_PER_FLUSH = 50;
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -1,103 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extension of {@link LuaValue} which can hold a Java boolean as its value. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * These instance are not instantiated directly by clients.  
 | 
			
		||||
 * Instead, there are exactly twon instances of this class, 
 | 
			
		||||
 * {@link LuaValue#TRUE} and {@link LuaValue#FALSE} 
 | 
			
		||||
 * representing the lua values {@code true} and {@link false}.
 | 
			
		||||
 * The function {@link LuaValue#valueOf(boolean)} will always 
 | 
			
		||||
 * return one of these two values. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Any {@link LuaValue} can be converted to its equivalent 
 | 
			
		||||
 * boolean representation using {@link LuaValue#toboolean()}
 | 
			
		||||
 * <p>
 | 
			
		||||
 * @see LuaValue
 | 
			
		||||
 * @see LuaValue#valueOf(boolean)
 | 
			
		||||
 * @see LuaValue#TRUE
 | 
			
		||||
 * @see LuaValue#FALSE
 | 
			
		||||
 */
 | 
			
		||||
public final class LuaBoolean extends LuaValue {
 | 
			
		||||
 | 
			
		||||
	/** The singleton instance representing lua {@code true} */
 | 
			
		||||
	static final LuaBoolean _TRUE = new LuaBoolean(true);
 | 
			
		||||
	
 | 
			
		||||
	/** The singleton instance representing lua {@code false} */
 | 
			
		||||
	static final LuaBoolean _FALSE = new LuaBoolean(false);
 | 
			
		||||
	
 | 
			
		||||
	/** Shared static metatable for boolean values represented in lua. */
 | 
			
		||||
	public static LuaValue s_metatable;
 | 
			
		||||
 | 
			
		||||
	/** The value of the boolean */
 | 
			
		||||
	public final boolean v;
 | 
			
		||||
 | 
			
		||||
	LuaBoolean(boolean b) {
 | 
			
		||||
		this.v = b;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int type() {
 | 
			
		||||
		return LuaValue.TBOOLEAN;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String typename() {
 | 
			
		||||
		return "boolean";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isboolean() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue not() {
 | 
			
		||||
		return v ? FALSE : LuaValue.TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the boolean value for this boolean
 | 
			
		||||
	 * @return value as a Java boolean
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean booleanValue() {
 | 
			
		||||
		return v;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean toboolean() {
 | 
			
		||||
		return v;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String tojstring() {
 | 
			
		||||
		return v ? "true" : "false";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean optboolean(boolean defval) {
 | 
			
		||||
		return this.v;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean checkboolean() {
 | 
			
		||||
		return v;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue getmetatable() { 
 | 
			
		||||
		return s_metatable; 
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,521 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
import java.io.ByteArrayInputStream;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LoadState.LuaCompiler;
 | 
			
		||||
import org.luaj.vm2.compiler.LuaC;
 | 
			
		||||
import org.luaj.vm2.lib.DebugLib;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extension of {@link LuaFunction} which executes lua bytecode. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * A {@link LuaClosure} is a combination of a {@link Prototype} 
 | 
			
		||||
 * and a {@link LuaValue} to use as an environment for execution. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * There are three main ways {@link LuaClosure} instances are created:
 | 
			
		||||
 * <ul> 
 | 
			
		||||
 * <li>Construct an instance using {@link #LuaClosure(Prototype, LuaValue)}</li>
 | 
			
		||||
 * <li>Construct it indirectly by loading a chunk via {@link LuaCompiler#load(java.io.InputStream, String, LuaValue)}
 | 
			
		||||
 * <li>Execute the lua bytecode {@link Lua#OP_CLOSURE} as part of bytecode processing
 | 
			
		||||
 * </ul>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To construct it directly, the {@link Prototype} is typically created via a compiler such as {@link LuaC}:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * InputStream is = new ByteArrayInputStream("print('hello,world').getBytes());
 | 
			
		||||
 * Prototype p = LuaC.instance.compile(is, "script");
 | 
			
		||||
 * LuaValue _G = JsePlatform.standardGlobals()
 | 
			
		||||
 * LuaClosure f = new LuaClosure(p, _G);
 | 
			
		||||
 * }</pre> 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To construct it indirectly, the {@link LuaC} compiler may be used, 
 | 
			
		||||
 * which implements the {@link LuaCompiler} interface: 
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LuaFunction f = LuaC.instance.load(is, "script", _G);
 | 
			
		||||
 * }</pre>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Typically, a closure that has just been loaded needs to be initialized by executing it, 
 | 
			
		||||
 * and its return value can be saved if needed:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LuaValue r = f.call();
 | 
			
		||||
 * _G.set( "mypkg", r ) 
 | 
			
		||||
 * }</pre>
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * In the preceding, the loaded value is typed as {@link LuaFunction} 
 | 
			
		||||
 * to allow for the possibility of other compilers such as {@link LuaJC}
 | 
			
		||||
 * producing {@link LuaFunction} directly without 
 | 
			
		||||
 * creating a {@link Prototype} or {@link LuaClosure}.
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * Since a {@link LuaClosure} is a {@link LuaFunction} which is a {@link LuaValue}, 
 | 
			
		||||
 * all the value operations can be used directly such as:
 | 
			
		||||
 * <ul>
 | 
			
		||||
 * <li>{@link LuaValue#setfenv(LuaValue)}</li>
 | 
			
		||||
 * <li>{@link LuaValue#call()}</li>
 | 
			
		||||
 * <li>{@link LuaValue#call(LuaValue)}</li>
 | 
			
		||||
 * <li>{@link LuaValue#invoke()}</li>
 | 
			
		||||
 * <li>{@link LuaValue#invoke(Varargs)}</li>
 | 
			
		||||
 * <li>{@link LuaValue#method(String)}</li>
 | 
			
		||||
 * <li>{@link LuaValue#method(String,LuaValue)}</li>
 | 
			
		||||
 * <li>{@link LuaValue#invokemethod(String)}</li>
 | 
			
		||||
 * <li>{@link LuaValue#invokemethod(String,Varargs)}</li>
 | 
			
		||||
 * <li> ...</li> 
 | 
			
		||||
 * </ul>
 | 
			
		||||
 * @see LuaValue
 | 
			
		||||
 * @see LuaFunction
 | 
			
		||||
 * @see LuaValue#isclosure()
 | 
			
		||||
 * @see LuaValue#checkclosure()
 | 
			
		||||
 * @see LuaValue#optclosure(LuaClosure)
 | 
			
		||||
 * @see LoadState
 | 
			
		||||
 * @see LoadState#compiler
 | 
			
		||||
 */
 | 
			
		||||
public class LuaClosure extends LuaFunction {
 | 
			
		||||
	private static final UpValue[] NOUPVALUES = new UpValue[0];
 | 
			
		||||
	
 | 
			
		||||
	public final Prototype p;
 | 
			
		||||
	public final UpValue[] upValues;
 | 
			
		||||
	
 | 
			
		||||
	LuaClosure() {
 | 
			
		||||
		p = null;
 | 
			
		||||
		upValues = null;
 | 
			
		||||
	}
 | 
			
		||||
	/** Supply the initial environment */
 | 
			
		||||
	public LuaClosure(Prototype p, LuaValue env) {
 | 
			
		||||
		super( env );
 | 
			
		||||
		this.p = p;
 | 
			
		||||
		this.upValues = p.nups>0? new UpValue[p.nups]: NOUPVALUES;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected LuaClosure(int nupvalues, LuaValue env) {
 | 
			
		||||
		super( env );
 | 
			
		||||
		this.p = null;
 | 
			
		||||
		this.upValues = nupvalues>0? new UpValue[nupvalues]: NOUPVALUES;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isclosure() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaClosure optclosure(LuaClosure defval) {
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaClosure checkclosure() {
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue getmetatable() { 
 | 
			
		||||
		return s_metatable; 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public final LuaValue call() {
 | 
			
		||||
		LuaValue[] stack = new LuaValue[p.maxstacksize];
 | 
			
		||||
		System.arraycopy(NILS, 0, stack, 0, p.maxstacksize);
 | 
			
		||||
		return execute(stack,NONE).arg1();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public final LuaValue call(LuaValue arg) {
 | 
			
		||||
		LuaValue[] stack = new LuaValue[p.maxstacksize];
 | 
			
		||||
		System.arraycopy(NILS, 0, stack, 0, p.maxstacksize);
 | 
			
		||||
		switch ( p.numparams ) {
 | 
			
		||||
		default: stack[0]=arg; return execute(stack,NONE).arg1();
 | 
			
		||||
		case 0: return execute(stack,arg).arg1();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public final LuaValue call(LuaValue arg1, LuaValue arg2) {
 | 
			
		||||
		LuaValue[] stack = new LuaValue[p.maxstacksize];
 | 
			
		||||
		System.arraycopy(NILS, 0, stack, 0, p.maxstacksize);
 | 
			
		||||
		switch ( p.numparams ) {
 | 
			
		||||
		default: stack[0]=arg1; stack[1]=arg2; return execute(stack,NONE).arg1();
 | 
			
		||||
		case 1: stack[0]=arg1; return execute(stack,arg2).arg1();
 | 
			
		||||
		case 0: return execute(stack,p.is_vararg!=0? varargsOf(arg1,arg2): NONE).arg1();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public final LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
 | 
			
		||||
		LuaValue[] stack = new LuaValue[p.maxstacksize];
 | 
			
		||||
		System.arraycopy(NILS, 0, stack, 0, p.maxstacksize);
 | 
			
		||||
		switch ( p.numparams ) {
 | 
			
		||||
		default: stack[0]=arg1; stack[1]=arg2; stack[2]=arg3; return execute(stack,NONE).arg1();
 | 
			
		||||
		case 2: stack[0]=arg1; stack[1]=arg2; return execute(stack,arg3).arg1();
 | 
			
		||||
		case 1: stack[0]=arg1; return execute(stack,p.is_vararg!=0? varargsOf(arg2,arg3): NONE).arg1();
 | 
			
		||||
		case 0: return execute(stack,p.is_vararg!=0? varargsOf(arg1,arg2,arg3): NONE).arg1();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public final Varargs invoke(Varargs varargs) {
 | 
			
		||||
		return onInvoke( varargs ).eval();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Varargs onInvoke(Varargs varargs) {
 | 
			
		||||
		LuaValue[] stack = new LuaValue[p.maxstacksize];
 | 
			
		||||
		System.arraycopy(NILS, 0, stack, 0, p.maxstacksize);
 | 
			
		||||
		for ( int i=0; i<p.numparams; i++ )
 | 
			
		||||
			stack[i] = varargs.arg(i+1);		
 | 
			
		||||
		return execute(stack,p.is_vararg!=0? varargs.subargs(p.numparams+1): NONE);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	protected Varargs execute( LuaValue[] stack, Varargs varargs ) {
 | 
			
		||||
		// loop through instructions
 | 
			
		||||
		int i,a,b,c,pc=0,top=0;
 | 
			
		||||
		LuaValue o;
 | 
			
		||||
		Varargs v = NONE;
 | 
			
		||||
		int[] code = p.code;
 | 
			
		||||
		LuaValue[] k = p.k;
 | 
			
		||||
		
 | 
			
		||||
		// upvalues are only possible when closures create closures
 | 
			
		||||
		UpValue[] openups = p.p.length>0? new UpValue[stack.length]: null;
 | 
			
		||||
		
 | 
			
		||||
		// create varargs "arg" table
 | 
			
		||||
		if ( p.is_vararg >= Lua.VARARG_NEEDSARG )
 | 
			
		||||
			stack[p.numparams] = new LuaTable(varargs);
 | 
			
		||||
 | 
			
		||||
		// debug wants args to this function
 | 
			
		||||
		if (DebugLib.DEBUG_ENABLED) 
 | 
			
		||||
			DebugLib.debugSetupCall(varargs, stack);
 | 
			
		||||
 | 
			
		||||
		// process instructions
 | 
			
		||||
		LuaThread.CallStack cs = LuaThread.onCall( this ); 
 | 
			
		||||
		try {
 | 
			
		||||
			while ( true ) {
 | 
			
		||||
				if (DebugLib.DEBUG_ENABLED) 
 | 
			
		||||
					DebugLib.debugBytecode(pc, v, top);
 | 
			
		||||
				
 | 
			
		||||
				// pull out instruction
 | 
			
		||||
				i = code[pc++];
 | 
			
		||||
				a = ((i>>6) & 0xff);
 | 
			
		||||
				
 | 
			
		||||
				// process the op code
 | 
			
		||||
				switch ( i & 0x3f ) {
 | 
			
		||||
				
 | 
			
		||||
				case Lua.OP_MOVE:/*	A B	R(A):= R(B)					*/
 | 
			
		||||
					stack[a] = stack[i>>>23];
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_LOADK:/*	A Bx	R(A):= Kst(Bx)					*/
 | 
			
		||||
					stack[a] = k[i>>>14];
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_LOADBOOL:/*	A B C	R(A):= (Bool)B: if (C) pc++			*/
 | 
			
		||||
	                stack[a] = (i>>>23!=0)? LuaValue.TRUE: LuaValue.FALSE;
 | 
			
		||||
	                if ((i&(0x1ff<<14)) != 0)
 | 
			
		||||
	                    pc++; /* skip next instruction (if C) */
 | 
			
		||||
	                continue;
 | 
			
		||||
	
 | 
			
		||||
				case Lua.OP_LOADNIL: /*	A B	R(A):= ...:= R(B):= nil			*/
 | 
			
		||||
					for ( b=i>>>23; a<=b; )
 | 
			
		||||
						stack[a++] = LuaValue.NIL;
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_GETUPVAL: /*	A B	R(A):= UpValue[B]				*/
 | 
			
		||||
	                stack[a] = upValues[i>>>23].getValue();
 | 
			
		||||
	                continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_GETGLOBAL: /*	A Bx	R(A):= Gbl[Kst(Bx)]				*/
 | 
			
		||||
	                stack[a] = env.get(k[i>>>14]);
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_GETTABLE: /*	A B C	R(A):= R(B)[RK(C)]				*/
 | 
			
		||||
	                stack[a] = stack[i>>>23].get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_SETGLOBAL: /*	A Bx	Gbl[Kst(Bx)]:= R(A)				*/
 | 
			
		||||
	                env.set(k[i>>>14], stack[a]);
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_SETUPVAL: /*	A B	UpValue[B]:= R(A)				*/
 | 
			
		||||
					upValues[i>>>23].setValue(stack[a]);
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_SETTABLE: /*	A B C	R(A)[RK(B)]:= RK(C)				*/
 | 
			
		||||
					stack[a].set(((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]), (c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_NEWTABLE: /*	A B C	R(A):= {} (size = B,C)				*/
 | 
			
		||||
					stack[a] = new LuaTable(i>>>23,(i>>14)&0x1ff);
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_SELF: /*	A B C	R(A+1):= R(B): R(A):= R(B)[RK(C)]		*/
 | 
			
		||||
					stack[a+1] = (o = stack[i>>>23]);
 | 
			
		||||
					stack[a] = o.get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_ADD: /*	A B C	R(A):= RK(B) + RK(C)				*/
 | 
			
		||||
					stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).add((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_SUB: /*	A B C	R(A):= RK(B) - RK(C)				*/
 | 
			
		||||
					stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).sub((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_MUL: /*	A B C	R(A):= RK(B) * RK(C)				*/
 | 
			
		||||
					stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).mul((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_DIV: /*	A B C	R(A):= RK(B) / RK(C)				*/
 | 
			
		||||
					stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).div((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_MOD: /*	A B C	R(A):= RK(B) % RK(C)				*/
 | 
			
		||||
					stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).mod((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_POW: /*	A B C	R(A):= RK(B) ^ RK(C)				*/
 | 
			
		||||
					stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).pow((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_UNM: /*	A B	R(A):= -R(B)					*/
 | 
			
		||||
					stack[a] = stack[i>>>23].neg();
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_NOT: /*	A B	R(A):= not R(B)				*/
 | 
			
		||||
					stack[a] = stack[i>>>23].not();
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_LEN: /*	A B	R(A):= length of R(B)				*/
 | 
			
		||||
					stack[a] = stack[i>>>23].len();
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_CONCAT: /*	A B C	R(A):= R(B).. ... ..R(C)			*/
 | 
			
		||||
					b = i>>>23;
 | 
			
		||||
					c = (i>>14)&0x1ff;
 | 
			
		||||
					{
 | 
			
		||||
						if ( c > b+1 ) {
 | 
			
		||||
							Buffer sb = stack[c].buffer();
 | 
			
		||||
							while ( --c>=b ) 
 | 
			
		||||
								sb = stack[c].concat(sb);
 | 
			
		||||
							stack[a] = sb.value();
 | 
			
		||||
						} else {
 | 
			
		||||
							stack[a] = stack[c-1].concat(stack[c]);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_JMP: /*	sBx	pc+=sBx					*/
 | 
			
		||||
					pc  += (i>>>14)-0x1ffff;
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_EQ: /*	A B C	if ((RK(B) == RK(C)) ~= A) then pc++		*/
 | 
			
		||||
					if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).eq_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) ) 
 | 
			
		||||
						++pc;
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_LT: /*	A B C	if ((RK(B) <  RK(C)) ~= A) then pc++  		*/
 | 
			
		||||
					if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).lt_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) ) 
 | 
			
		||||
						++pc;
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_LE: /*	A B C	if ((RK(B) <= RK(C)) ~= A) then pc++  		*/
 | 
			
		||||
					if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).lteq_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) ) 
 | 
			
		||||
						++pc;
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_TEST: /*	A C	if not (R(A) <=> C) then pc++			*/ 
 | 
			
		||||
					if ( stack[a].toboolean() != ((i&(0x1ff<<14))!=0) ) 
 | 
			
		||||
						++pc;
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_TESTSET: /*	A B C	if (R(B) <=> C) then R(A):= R(B) else pc++	*/
 | 
			
		||||
					/* note: doc appears to be reversed */
 | 
			
		||||
					if ( (o=stack[i>>>23]).toboolean() != ((i&(0x1ff<<14))!=0) ) 
 | 
			
		||||
						++pc;
 | 
			
		||||
					else
 | 
			
		||||
						stack[a] = o; // TODO: should be sBx? 
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_CALL: /*	A B C	R(A), ... ,R(A+C-2):= R(A)(R(A+1), ... ,R(A+B-1)) */
 | 
			
		||||
					switch ( i & (Lua.MASK_B | Lua.MASK_C) ) {
 | 
			
		||||
					case (1<<Lua.POS_B) | (0<<Lua.POS_C): v=stack[a].invoke(NONE); top=a+v.narg(); continue;
 | 
			
		||||
					case (2<<Lua.POS_B) | (0<<Lua.POS_C): v=stack[a].invoke(stack[a+1]); top=a+v.narg(); continue;
 | 
			
		||||
					case (1<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(); continue;
 | 
			
		||||
					case (2<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1]); continue;
 | 
			
		||||
					case (3<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1],stack[a+2]); continue;
 | 
			
		||||
					case (4<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1],stack[a+2],stack[a+3]); continue;
 | 
			
		||||
					case (1<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(); continue;
 | 
			
		||||
					case (2<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1]); continue;
 | 
			
		||||
					case (3<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1],stack[a+2]); continue;
 | 
			
		||||
					case (4<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1],stack[a+2],stack[a+3]); continue;
 | 
			
		||||
					default:
 | 
			
		||||
						b = i>>>23;
 | 
			
		||||
						c = (i>>14)&0x1ff;
 | 
			
		||||
						v = b>0? 
 | 
			
		||||
							varargsOf(stack,a+1,b-1): // exact arg count
 | 
			
		||||
							varargsOf(stack, a+1, top-v.narg()-(a+1), v); // from prev top 
 | 
			
		||||
						v = stack[a].invoke(v);
 | 
			
		||||
						if ( c > 0 ) {
 | 
			
		||||
							while ( --c > 0 )
 | 
			
		||||
								stack[a+c-1] = v.arg(c);
 | 
			
		||||
							v = NONE; // TODO: necessary?
 | 
			
		||||
						} else {
 | 
			
		||||
							top = a + v.narg();
 | 
			
		||||
						}
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_TAILCALL: /*	A B C	return R(A)(R(A+1), ... ,R(A+B-1))		*/
 | 
			
		||||
					switch ( i & Lua.MASK_B ) {
 | 
			
		||||
					case (1<<Lua.POS_B): return new TailcallVarargs(stack[a], NONE);
 | 
			
		||||
					case (2<<Lua.POS_B): return new TailcallVarargs(stack[a], stack[a+1]);
 | 
			
		||||
					case (3<<Lua.POS_B): return new TailcallVarargs(stack[a], varargsOf(stack[a+1],stack[a+2]));
 | 
			
		||||
					case (4<<Lua.POS_B): return new TailcallVarargs(stack[a], varargsOf(stack[a+1],stack[a+2],stack[a+3]));
 | 
			
		||||
					default:
 | 
			
		||||
						b = i>>>23;
 | 
			
		||||
						v = b>0? 
 | 
			
		||||
							varargsOf(stack,a+1,b-1): // exact arg count
 | 
			
		||||
							varargsOf(stack, a+1, top-v.narg()-(a+1), v); // from prev top 
 | 
			
		||||
						return new TailcallVarargs( stack[a], v );
 | 
			
		||||
					}
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_RETURN: /*	A B	return R(A), ... ,R(A+B-2)	(see note)	*/
 | 
			
		||||
					b = i>>>23;
 | 
			
		||||
					switch ( b ) {
 | 
			
		||||
					case 0: return varargsOf(stack, a, top-v.narg()-a, v); 
 | 
			
		||||
					case 1: return NONE;
 | 
			
		||||
					case 2: return stack[a]; 
 | 
			
		||||
					default:
 | 
			
		||||
						return varargsOf(stack, a, b-1);
 | 
			
		||||
					}
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_FORLOOP: /*	A sBx	R(A)+=R(A+2): if R(A) <?= R(A+1) then { pc+=sBx: R(A+3)=R(A) }*/
 | 
			
		||||
					{
 | 
			
		||||
			            LuaValue limit = stack[a + 1];
 | 
			
		||||
						LuaValue step  = stack[a + 2];
 | 
			
		||||
						LuaValue idx   = step.add(stack[a]);
 | 
			
		||||
			            if (step.gt_b(0)? idx.lteq_b(limit): idx.gteq_b(limit)) {
 | 
			
		||||
		                    stack[a] = idx;
 | 
			
		||||
		                    stack[a + 3] = idx;
 | 
			
		||||
		                    pc += (i>>>14)-0x1ffff;
 | 
			
		||||
			            }
 | 
			
		||||
					}
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_FORPREP: /*	A sBx	R(A)-=R(A+2): pc+=sBx				*/
 | 
			
		||||
					{
 | 
			
		||||
						LuaValue init  = stack[a].checknumber("'for' initial value must be a number");
 | 
			
		||||
						LuaValue limit = stack[a + 1].checknumber("'for' limit must be a number");
 | 
			
		||||
						LuaValue step  = stack[a + 2].checknumber("'for' step must be a number");
 | 
			
		||||
						stack[a] = init.sub(step);
 | 
			
		||||
						stack[a + 1] = limit;
 | 
			
		||||
						stack[a + 2] = step;
 | 
			
		||||
						pc += (i>>>14)-0x1ffff;
 | 
			
		||||
					}
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_TFORLOOP: /*
 | 
			
		||||
									 * A C R(A+3), ... ,R(A+2+C):= R(A)(R(A+1),
 | 
			
		||||
									 * R(A+2)): if R(A+3) ~= nil then R(A+2)=R(A+3)
 | 
			
		||||
									 * else pc++
 | 
			
		||||
									 */
 | 
			
		||||
					// TODO: stack call on for loop body, such as:   stack[a].call(ci);
 | 
			
		||||
					v = stack[a].invoke(varargsOf(stack[a+1],stack[a+2]));
 | 
			
		||||
					if ( (o=v.arg1()).isnil() )
 | 
			
		||||
						++pc;
 | 
			
		||||
					else {
 | 
			
		||||
						stack[a+2] = stack[a+3] = o;
 | 
			
		||||
						for ( c=(i>>14)&0x1ff; c>1; --c )
 | 
			
		||||
							stack[a+2+c] = v.arg(c);
 | 
			
		||||
						v = NONE; // todo: necessary? 
 | 
			
		||||
					}
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_SETLIST: /*	A B C	R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B	*/
 | 
			
		||||
					{
 | 
			
		||||
		                if ( (c=(i>>14)&0x1ff) == 0 )
 | 
			
		||||
		                    c = code[pc++];
 | 
			
		||||
		                int offset = (c-1) * Lua.LFIELDS_PER_FLUSH;
 | 
			
		||||
		                o = stack[a];
 | 
			
		||||
		                if ( (b=i>>>23) == 0 ) {
 | 
			
		||||
		                    b = top - a - 1;
 | 
			
		||||
		                    int m = b - v.narg(); 
 | 
			
		||||
		                	int j=1;
 | 
			
		||||
		                	for ( ;j<=m; j++ )
 | 
			
		||||
		                    	o.set(offset+j, stack[a + j]);
 | 
			
		||||
		                	for ( ;j<=b; j++ )
 | 
			
		||||
		                    	o.set(offset+j, v.arg(j-m));
 | 
			
		||||
		                } else {
 | 
			
		||||
		                    o.presize( offset + b );
 | 
			
		||||
		                    for (int j=1; j<=b; j++)
 | 
			
		||||
		                    	o.set(offset+j, stack[a + j]);
 | 
			
		||||
		                }
 | 
			
		||||
					}
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_CLOSE: /*	A 	close all variables in the stack up to (>=) R(A)*/
 | 
			
		||||
					for ( b=openups.length; --b>=a; )
 | 
			
		||||
						if ( openups[b]!=null ) {
 | 
			
		||||
							openups[b].close();
 | 
			
		||||
							openups[b] = null;
 | 
			
		||||
						}
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_CLOSURE: /*	A Bx	R(A):= closure(KPROTO[Bx], R(A), ... ,R(A+n))	*/
 | 
			
		||||
					{
 | 
			
		||||
						Prototype newp = p.p[i>>>14];
 | 
			
		||||
						LuaClosure newcl = new LuaClosure(newp, env);
 | 
			
		||||
						for ( int j=0, nup=newp.nups; j<nup; ++j ) {
 | 
			
		||||
							i = code[pc++];
 | 
			
		||||
							//b = B(i);
 | 
			
		||||
							b = i>>>23;
 | 
			
		||||
							newcl.upValues[j] = (i&4) != 0? 
 | 
			
		||||
									upValues[b]:
 | 
			
		||||
									openups[b]!=null? openups[b]: (openups[b]=new UpValue(stack,b));
 | 
			
		||||
						}
 | 
			
		||||
						stack[a] = newcl;
 | 
			
		||||
					}
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				case Lua.OP_VARARG: /*	A B	R(A), R(A+1), ..., R(A+B-1) = vararg		*/
 | 
			
		||||
					b = i>>>23;
 | 
			
		||||
					if ( b == 0 ) {
 | 
			
		||||
						top = a + (b = varargs.narg());
 | 
			
		||||
						v = varargs;
 | 
			
		||||
					} else { 
 | 
			
		||||
						for ( int j=1; j<b; ++j )
 | 
			
		||||
							stack[a+j-1] = varargs.arg(j);
 | 
			
		||||
					}
 | 
			
		||||
					continue;				
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} catch ( LuaError le ) {
 | 
			
		||||
			throw le;
 | 
			
		||||
		} catch ( Exception e ) {
 | 
			
		||||
			throw new LuaError(e);
 | 
			
		||||
		} finally {
 | 
			
		||||
			cs.onReturn();
 | 
			
		||||
			if ( openups != null )
 | 
			
		||||
				for ( int u=openups.length; --u>=0; )
 | 
			
		||||
					if ( openups[u] != null )
 | 
			
		||||
						openups[u].close();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	protected LuaValue getUpvalue(int i) {
 | 
			
		||||
		return upValues[i].getValue();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected void setUpvalue(int i, LuaValue v) {
 | 
			
		||||
		upValues[i].setValue(v);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,288 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.lib.MathLib;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extension of {@link LuaNumber} which can hold a Java double as its value. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * These instance are not instantiated directly by clients, but indirectly 
 | 
			
		||||
 * via the static functions {@link LuaValue#valueOf(int)} or {@link LuaValue#valueOf(double)}
 | 
			
		||||
 * functions.  This ensures that values which can be represented as int 
 | 
			
		||||
 * are wrapped in {@link LuaInteger} instead of {@link LuaDouble}.  
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Almost all API's implemented in LuaDouble are defined and documented in {@link LuaValue}.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * However the constants {@link #NAN}, {@link #POSINF}, {@link #NEGINF},
 | 
			
		||||
 * {@link #JSTR_NAN}, {@link #JSTR_POSINF}, and {@link #JSTR_NEGINF} may be useful 
 | 
			
		||||
 * when dealing with Nan or Infinite values. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * LuaDouble also defines functions for handling the unique math rules of lua devision and modulo in
 | 
			
		||||
 * <ul>
 | 
			
		||||
 * <li>{@link #ddiv(double, double)}</li>
 | 
			
		||||
 * <li>{@link #ddiv_d(double, double)}</li>
 | 
			
		||||
 * <li>{@link #dmod(double, double)}</li>
 | 
			
		||||
 * <li>{@link #dmod_d(double, double)}</li>
 | 
			
		||||
 * </ul> 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * @see LuaValue
 | 
			
		||||
 * @see LuaNumber
 | 
			
		||||
 * @see LuaInteger
 | 
			
		||||
 * @see LuaValue#valueOf(int)
 | 
			
		||||
 * @see LuaValue#valueOf(double)
 | 
			
		||||
 */
 | 
			
		||||
public class LuaDouble extends LuaNumber {
 | 
			
		||||
 | 
			
		||||
	/** Constant LuaDouble representing NaN (not a number) */
 | 
			
		||||
	public static final LuaDouble NAN    = new LuaDouble( Double.NaN );
 | 
			
		||||
	
 | 
			
		||||
	/** Constant LuaDouble representing positive infinity */
 | 
			
		||||
	public static final LuaDouble POSINF = new LuaDouble( Double.POSITIVE_INFINITY );
 | 
			
		||||
	
 | 
			
		||||
	/** Constant LuaDouble representing negative infinity */
 | 
			
		||||
	public static final LuaDouble NEGINF = new LuaDouble( Double.NEGATIVE_INFINITY );
 | 
			
		||||
	
 | 
			
		||||
	/** Constant String representation for NaN (not a number), "nan" */
 | 
			
		||||
	public static final String JSTR_NAN    = "nan";
 | 
			
		||||
	
 | 
			
		||||
	/** Constant String representation for positive infinity, "inf" */
 | 
			
		||||
	public static final String JSTR_POSINF = "inf";
 | 
			
		||||
 | 
			
		||||
	/** Constant String representation for negative infinity, "-inf" */
 | 
			
		||||
	public static final String JSTR_NEGINF = "-inf";
 | 
			
		||||
	
 | 
			
		||||
	/** The value being held by this instance. */
 | 
			
		||||
	final double v;
 | 
			
		||||
 | 
			
		||||
	public static LuaNumber valueOf(double d) {
 | 
			
		||||
		int id = (int) d;
 | 
			
		||||
		return d==id? (LuaNumber) LuaInteger.valueOf(id): (LuaNumber) new LuaDouble(d);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Don't allow ints to be boxed by DoubleValues  */
 | 
			
		||||
	private LuaDouble(double d) {
 | 
			
		||||
		this.v = d;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int hashCode() {
 | 
			
		||||
		long l = Double.doubleToLongBits(v);
 | 
			
		||||
		return ((int)(l>>32)) | (int) l;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean islong() {
 | 
			
		||||
		return v == (long) v; 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public byte    tobyte()        { return (byte) (long) v; }
 | 
			
		||||
	public char    tochar()        { return (char) (long) v; }
 | 
			
		||||
	public double  todouble()      { return v; }
 | 
			
		||||
	public float   tofloat()       { return (float) v; }
 | 
			
		||||
	public int     toint()         { return (int) (long) v; }
 | 
			
		||||
	public long    tolong()        { return (long) v; }
 | 
			
		||||
	public short   toshort()       { return (short) (long) v; }
 | 
			
		||||
 | 
			
		||||
	public double      optdouble(double defval)        { return v; }
 | 
			
		||||
	public int         optint(int defval)              { return (int) (long) v;  }
 | 
			
		||||
	public LuaInteger  optinteger(LuaInteger defval)   { return LuaInteger.valueOf((int) (long)v); }
 | 
			
		||||
	public long        optlong(long defval)            { return (long) v; }
 | 
			
		||||
	
 | 
			
		||||
	public LuaInteger  checkinteger()                  { return LuaInteger.valueOf( (int) (long) v ); }
 | 
			
		||||
	
 | 
			
		||||
	// unary operators
 | 
			
		||||
	public LuaValue neg() { return valueOf(-v); }
 | 
			
		||||
	
 | 
			
		||||
	// object equality, used for key comparison
 | 
			
		||||
	public boolean equals(Object o) { return o instanceof LuaDouble? ((LuaDouble)o).v == v: false; }
 | 
			
		||||
	
 | 
			
		||||
	// equality w/ metatable processing
 | 
			
		||||
	public LuaValue eq( LuaValue val )        { return val.raweq(v)? TRUE: FALSE; }
 | 
			
		||||
	public boolean eq_b( LuaValue val )       { return val.raweq(v); }
 | 
			
		||||
 | 
			
		||||
	// equality w/o metatable processing
 | 
			
		||||
	public boolean raweq( LuaValue val )      { return val.raweq(v); }
 | 
			
		||||
	public boolean raweq( double val )        { return v == val; }
 | 
			
		||||
	public boolean raweq( int val )           { return v == val; }
 | 
			
		||||
	
 | 
			
		||||
	// basic binary arithmetic
 | 
			
		||||
	public LuaValue   add( LuaValue rhs )        { return rhs.add(v); }
 | 
			
		||||
	public LuaValue   add( double lhs )     { return LuaDouble.valueOf(lhs + v); }
 | 
			
		||||
	public LuaValue   sub( LuaValue rhs )        { return rhs.subFrom(v); }
 | 
			
		||||
	public LuaValue   sub( double rhs )        { return LuaDouble.valueOf(v - rhs); }
 | 
			
		||||
	public LuaValue   sub( int rhs )        { return LuaDouble.valueOf(v - rhs); }
 | 
			
		||||
	public LuaValue   subFrom( double lhs )   { return LuaDouble.valueOf(lhs - v); }
 | 
			
		||||
	public LuaValue   mul( LuaValue rhs )        { return rhs.mul(v); }
 | 
			
		||||
	public LuaValue   mul( double lhs )   { return LuaDouble.valueOf(lhs * v); }
 | 
			
		||||
	public LuaValue   mul( int lhs )      { return LuaDouble.valueOf(lhs * v); }
 | 
			
		||||
	public LuaValue   pow( LuaValue rhs )        { return rhs.powWith(v); }
 | 
			
		||||
	public LuaValue   pow( double rhs )        { return MathLib.dpow(v,rhs); }
 | 
			
		||||
	public LuaValue   pow( int rhs )        { return MathLib.dpow(v,rhs); }
 | 
			
		||||
	public LuaValue   powWith( double lhs )   { return MathLib.dpow(lhs,v); }
 | 
			
		||||
	public LuaValue   powWith( int lhs )      { return MathLib.dpow(lhs,v); }
 | 
			
		||||
	public LuaValue   div( LuaValue rhs )        { return rhs.divInto(v); }
 | 
			
		||||
	public LuaValue   div( double rhs )        { return LuaDouble.ddiv(v,rhs); }
 | 
			
		||||
	public LuaValue   div( int rhs )        { return LuaDouble.ddiv(v,rhs); }
 | 
			
		||||
	public LuaValue   divInto( double lhs )   { return LuaDouble.ddiv(lhs,v); }
 | 
			
		||||
	public LuaValue   mod( LuaValue rhs )        { return rhs.modFrom(v); }
 | 
			
		||||
	public LuaValue   mod( double rhs )        { return LuaDouble.dmod(v,rhs); }
 | 
			
		||||
	public LuaValue   mod( int rhs )        { return LuaDouble.dmod(v,rhs); }
 | 
			
		||||
	public LuaValue   modFrom( double lhs )   { return LuaDouble.dmod(lhs,v); }
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	/** Divide two double numbers according to lua math, and return a {@link LuaValue} result.
 | 
			
		||||
	 * @param lhs Left-hand-side of the division.
 | 
			
		||||
	 * @param rhs Right-hand-side of the division.
 | 
			
		||||
	 * @return {@link LuaValue} for the result of the division, 
 | 
			
		||||
	 * taking into account positive and negiative infinity, and Nan
 | 
			
		||||
	 * @see #ddiv_d(double, double) 
 | 
			
		||||
	 */
 | 
			
		||||
	public static LuaValue ddiv(double lhs, double rhs) {
 | 
			
		||||
		return rhs!=0? valueOf( lhs / rhs ): lhs>0? POSINF: lhs==0? NAN: NEGINF;	
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Divide two double numbers according to lua math, and return a double result.
 | 
			
		||||
	 * @param lhs Left-hand-side of the division.
 | 
			
		||||
	 * @param rhs Right-hand-side of the division.
 | 
			
		||||
	 * @return Value of the division, taking into account positive and negative infinity, and Nan
 | 
			
		||||
	 * @see #ddiv(double, double)
 | 
			
		||||
	 */
 | 
			
		||||
	public static double ddiv_d(double lhs, double rhs) {
 | 
			
		||||
		return rhs!=0? lhs / rhs: lhs>0? Double.POSITIVE_INFINITY: lhs==0? Double.NaN: Double.NEGATIVE_INFINITY;	
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Take modulo double numbers according to lua math, and return a {@link LuaValue} result.
 | 
			
		||||
	 * @param lhs Left-hand-side of the modulo.
 | 
			
		||||
	 * @param rhs Right-hand-side of the modulo.
 | 
			
		||||
	 * @return {@link LuaValue} for the result of the modulo, 
 | 
			
		||||
	 * using lua's rules for modulo
 | 
			
		||||
	 * @see #dmod_d(double, double) 
 | 
			
		||||
	 */
 | 
			
		||||
	public static LuaValue dmod(double lhs, double rhs) {
 | 
			
		||||
		return rhs!=0? valueOf( lhs-rhs*Math.floor(lhs/rhs) ): NAN;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Take modulo for double numbers according to lua math, and return a double result.
 | 
			
		||||
	 * @param lhs Left-hand-side of the modulo.
 | 
			
		||||
	 * @param rhs Right-hand-side of the modulo.
 | 
			
		||||
	 * @return double value for the result of the modulo, 
 | 
			
		||||
	 * using lua's rules for modulo
 | 
			
		||||
	 * @see #dmod(double, double)
 | 
			
		||||
	 */
 | 
			
		||||
	public static double dmod_d(double lhs, double rhs) {
 | 
			
		||||
		return rhs!=0? lhs-rhs*Math.floor(lhs/rhs): Double.NaN;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// relational operators
 | 
			
		||||
	public LuaValue   lt( LuaValue rhs )         { return rhs.gt_b(v)? LuaValue.TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   lt( double rhs )      { return v < rhs? TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   lt( int rhs )         { return v < rhs? TRUE: FALSE; }
 | 
			
		||||
	public boolean lt_b( LuaValue rhs )       { return rhs.gt_b(v); }
 | 
			
		||||
	public boolean lt_b( int rhs )         { return v < rhs; }
 | 
			
		||||
	public boolean lt_b( double rhs )      { return v < rhs; }
 | 
			
		||||
	public LuaValue   lteq( LuaValue rhs )       { return rhs.gteq_b(v)? LuaValue.TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   lteq( double rhs )    { return v <= rhs? TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   lteq( int rhs )       { return v <= rhs? TRUE: FALSE; }
 | 
			
		||||
	public boolean lteq_b( LuaValue rhs )     { return rhs.gteq_b(v); }
 | 
			
		||||
	public boolean lteq_b( int rhs )       { return v <= rhs; }
 | 
			
		||||
	public boolean lteq_b( double rhs )    { return v <= rhs; }
 | 
			
		||||
	public LuaValue   gt( LuaValue rhs )         { return rhs.lt_b(v)? LuaValue.TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   gt( double rhs )      { return v > rhs? TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   gt( int rhs )         { return v > rhs? TRUE: FALSE; }
 | 
			
		||||
	public boolean gt_b( LuaValue rhs )       { return rhs.lt_b(v); }
 | 
			
		||||
	public boolean gt_b( int rhs )         { return v > rhs; }
 | 
			
		||||
	public boolean gt_b( double rhs )      { return v > rhs; }
 | 
			
		||||
	public LuaValue   gteq( LuaValue rhs )       { return rhs.lteq_b(v)? LuaValue.TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   gteq( double rhs )    { return v >= rhs? TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   gteq( int rhs )       { return v >= rhs? TRUE: FALSE; }
 | 
			
		||||
	public boolean gteq_b( LuaValue rhs )     { return rhs.lteq_b(v); }
 | 
			
		||||
	public boolean gteq_b( int rhs )       { return v >= rhs; }
 | 
			
		||||
	public boolean gteq_b( double rhs )    { return v >= rhs; }
 | 
			
		||||
	
 | 
			
		||||
	// string comparison
 | 
			
		||||
	public int strcmp( LuaString rhs )      { typerror("attempt to compare number with string"); return 0; }
 | 
			
		||||
			
 | 
			
		||||
	public String tojstring() {
 | 
			
		||||
		/*
 | 
			
		||||
		if ( v == 0.0 ) { // never occurs in J2me 
 | 
			
		||||
			long bits = Double.doubleToLongBits( v );
 | 
			
		||||
			return ( bits >> 63 == 0 ) ? "0" : "-0";
 | 
			
		||||
		}
 | 
			
		||||
		*/
 | 
			
		||||
		long l = (long) v;
 | 
			
		||||
		if ( l == v ) 
 | 
			
		||||
			return Long.toString(l);
 | 
			
		||||
		if ( Double.isNaN(v) )
 | 
			
		||||
			return JSTR_NAN;
 | 
			
		||||
		if ( Double.isInfinite(v) ) 
 | 
			
		||||
			return (v<0? JSTR_NEGINF: JSTR_POSINF);
 | 
			
		||||
		return Float.toString((float)v);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaString strvalue() {
 | 
			
		||||
		return LuaString.valueOf(tojstring());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaString optstring(LuaString defval) {
 | 
			
		||||
		return LuaString.valueOf(tojstring());
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
	public LuaValue tostring() {
 | 
			
		||||
		return LuaString.valueOf(tojstring());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public String optjstring(String defval) {
 | 
			
		||||
		return tojstring();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaNumber optnumber(LuaNumber defval) {
 | 
			
		||||
		return this; 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isnumber() {
 | 
			
		||||
		return true; 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isstring() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue tonumber() {
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	public int checkint()                { return (int) (long) v; }
 | 
			
		||||
	public long checklong()              { return (long) v; }
 | 
			
		||||
	public LuaNumber checknumber()       { return this; }
 | 
			
		||||
	public double checkdouble()          { return v; }
 | 
			
		||||
	
 | 
			
		||||
	public String checkjstring() { 
 | 
			
		||||
		return tojstring();
 | 
			
		||||
	}
 | 
			
		||||
	public LuaString checkstring() { 
 | 
			
		||||
		return LuaString.valueOf(tojstring());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue checkvalidkey() {
 | 
			
		||||
		if ( Double.isNaN(v) )
 | 
			
		||||
			throw new LuaError("table index expected, got nan");
 | 
			
		||||
		return this; 
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
@@ -1,132 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.lib.DebugLib;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * RuntimeException that is thrown and caught in response to a lua error. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * {@link LuaError} is used wherever a lua call to {@code error()} 
 | 
			
		||||
 * would be used within a script.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Since it is an unchecked exception inheriting from {@link RuntimeException},
 | 
			
		||||
 * Java method signatures do notdeclare this exception, althoug it can 
 | 
			
		||||
 * be thrown on almost any luaj Java operation.
 | 
			
		||||
 * This is analagous to the fact that any lua script can throw a lua error at any time.
 | 
			
		||||
 * <p>   
 | 
			
		||||
 */
 | 
			
		||||
public class LuaError extends RuntimeException {
 | 
			
		||||
	private static final long serialVersionUID = 1L;
 | 
			
		||||
	
 | 
			
		||||
	private String traceback;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 *  Run the error hook if there is one
 | 
			
		||||
	 *  @param msg the message to use in error hook processing. 
 | 
			
		||||
	 * */
 | 
			
		||||
	private static String errorHook(String msg) {
 | 
			
		||||
		LuaThread thread = LuaThread.getRunning();
 | 
			
		||||
		if ( thread.err != null ) { 
 | 
			
		||||
			LuaValue errfunc = thread.err;
 | 
			
		||||
			thread.err = null;
 | 
			
		||||
			try {
 | 
			
		||||
				return errfunc.call( LuaValue.valueOf(msg) ).tojstring();
 | 
			
		||||
			} catch ( Throwable t ) {
 | 
			
		||||
				return "error in error handling";
 | 
			
		||||
			} finally {
 | 
			
		||||
				thread.err = errfunc;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return msg;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private Throwable cause;
 | 
			
		||||
	
 | 
			
		||||
	/** Construct LuaError when a program exception occurs. 
 | 
			
		||||
	 * <p> 
 | 
			
		||||
	 * All errors generated from lua code should throw LuaError(String) instead.
 | 
			
		||||
	 * @param cause the Throwable that caused the error, if known.  
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaError(Throwable cause) {
 | 
			
		||||
		super( errorHook( addFileLine( "vm error: "+cause ) ) );
 | 
			
		||||
		this.cause = cause;
 | 
			
		||||
		this.traceback = DebugLib.traceback(1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Construct a LuaError with a specific message.  
 | 
			
		||||
	 *  
 | 
			
		||||
	 * @param message message to supply
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaError(String message) {
 | 
			
		||||
		super( errorHook( addFileLine( message ) ) );
 | 
			
		||||
		this.traceback = DebugLib.traceback(1);
 | 
			
		||||
	}		
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Construct a LuaError with a message, and level to draw line number information from.
 | 
			
		||||
	 * @param message message to supply
 | 
			
		||||
	 * @param level where to supply line info from in call stack
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaError(String message, int level) {
 | 
			
		||||
		super( errorHook( addFileLine( message, level ) ) );
 | 
			
		||||
		this.traceback = DebugLib.traceback(1);
 | 
			
		||||
	}	
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Add file and line info to a message at a particular level 
 | 
			
		||||
	 * @param message the String message to use
 | 
			
		||||
	 * @param level where to supply line info from in call stack
 | 
			
		||||
	 * */
 | 
			
		||||
	private static String addFileLine( String message, int level ) {
 | 
			
		||||
		if ( message == null ) return null;
 | 
			
		||||
		if ( level == 0 ) return message;
 | 
			
		||||
		String fileline = DebugLib.fileline(level-1);
 | 
			
		||||
		return fileline!=null? fileline+": "+message: message;		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Add file and line info for the nearest enclosing closure
 | 
			
		||||
	 * @param message the String message to use
 | 
			
		||||
	 * */
 | 
			
		||||
	private static String addFileLine( String message ) {
 | 
			
		||||
		if ( message == null ) return null;
 | 
			
		||||
		String fileline = DebugLib.fileline();
 | 
			
		||||
		return fileline!=null? fileline+": "+message: message;		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Print the message and stack trace */
 | 
			
		||||
	public void printStackTrace() {
 | 
			
		||||
		System.out.println( toString() );
 | 
			
		||||
		if ( traceback != null )
 | 
			
		||||
			System.out.println( traceback );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Get the cause, if any.
 | 
			
		||||
	 */
 | 
			
		||||
	public Throwable getCause() {
 | 
			
		||||
		return cause;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,82 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Base class for functions implemented in Java. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Direct subclass include {@link LibFunction} which is the base class for 
 | 
			
		||||
 * all built-in library functions coded in Java, 
 | 
			
		||||
 * and {@link LuaClosure}, which represents a lua closure 
 | 
			
		||||
 * whose bytecode is interpreted when the function is invoked.    
 | 
			
		||||
 * @see LuaValue
 | 
			
		||||
 * @see LibFunction
 | 
			
		||||
 * @see LuaClosure
 | 
			
		||||
 */
 | 
			
		||||
abstract
 | 
			
		||||
public class LuaFunction extends LuaValue {
 | 
			
		||||
	
 | 
			
		||||
	/** Shared static metatable for all functions and closures. */
 | 
			
		||||
	public static LuaValue s_metatable;
 | 
			
		||||
 | 
			
		||||
	protected LuaValue env;
 | 
			
		||||
	
 | 
			
		||||
	public LuaFunction() {
 | 
			
		||||
		this.env = NIL;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaFunction(LuaValue env) {
 | 
			
		||||
		this.env = env;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int type() {
 | 
			
		||||
		return TFUNCTION;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public String typename() {
 | 
			
		||||
		return "function";
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isfunction() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue checkfunction()  {
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaFunction optfunction(LuaFunction defval) {
 | 
			
		||||
		return this; 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue getmetatable() { 
 | 
			
		||||
		return s_metatable; 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue getfenv() {
 | 
			
		||||
		return env;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setfenv(LuaValue env) {
 | 
			
		||||
		this.env = env!=null? env: NIL;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,215 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.lib.MathLib;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extension of {@link LuaNumber} which can hold a Java int as its value. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * These instance are not instantiated directly by clients, but indirectly 
 | 
			
		||||
 * via the static functions {@link LuaValue#valueOf(int)} or {@link LuaValue#valueOf(double)}
 | 
			
		||||
 * functions.  This ensures that policies regarding pooling of instances are 
 | 
			
		||||
 * encapsulated.  
 | 
			
		||||
 * <p>
 | 
			
		||||
 * There are no API's specific to LuaInteger that are useful beyond what is already 
 | 
			
		||||
 * exposed in {@link LuaValue}.
 | 
			
		||||
 * 
 | 
			
		||||
 * @see LuaValue
 | 
			
		||||
 * @see LuaNumber
 | 
			
		||||
 * @see LuaDouble
 | 
			
		||||
 * @see LuaValue#valueOf(int)
 | 
			
		||||
 * @see LuaValue#valueOf(double)
 | 
			
		||||
 */
 | 
			
		||||
public class LuaInteger extends LuaNumber {
 | 
			
		||||
 | 
			
		||||
	private static final LuaInteger[] intValues = new LuaInteger[512];
 | 
			
		||||
	static {
 | 
			
		||||
		for ( int i=0; i<512; i++ )
 | 
			
		||||
			intValues[i] = new LuaInteger(i-256);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static LuaInteger valueOf(int i) {
 | 
			
		||||
		return i<=255 && i>=-256? intValues[i+256]: new LuaInteger(i);
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
	 // TODO consider moving this to LuaValue
 | 
			
		||||
	/** Return a LuaNumber that represents the value provided
 | 
			
		||||
	 * @param l long value to represent.
 | 
			
		||||
	 * @return LuaNumber that is eithe LuaInteger or LuaDouble representing l
 | 
			
		||||
	 * @see LuaValue#valueOf(int)
 | 
			
		||||
	 * @see LuaValue#valueOf(double)
 | 
			
		||||
	 */
 | 
			
		||||
	public static LuaNumber valueOf(long l) {
 | 
			
		||||
		int i = (int) l;
 | 
			
		||||
		return l==i? (i<=255 && i>=-256? intValues[i+256]: 
 | 
			
		||||
			(LuaNumber) new LuaInteger(i)): 
 | 
			
		||||
			(LuaNumber) LuaDouble.valueOf(l);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** The value being held by this instance. */
 | 
			
		||||
	public final int v;
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Package protected constructor. 
 | 
			
		||||
	 * @see LuaValue#valueOf(int)
 | 
			
		||||
	 **/
 | 
			
		||||
	LuaInteger(int i) {
 | 
			
		||||
		this.v = i;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isint() {		return true;	}
 | 
			
		||||
	public boolean isinttype() {	return true;	}
 | 
			
		||||
	public boolean islong() {		return true;	}
 | 
			
		||||
	
 | 
			
		||||
	public byte    tobyte()        { return (byte) v; }
 | 
			
		||||
	public char    tochar()        { return (char) v; }
 | 
			
		||||
	public double  todouble()      { return v; }
 | 
			
		||||
	public float   tofloat()       { return v; }
 | 
			
		||||
	public int     toint()         { return v; }
 | 
			
		||||
	public long    tolong()        { return v; }
 | 
			
		||||
	public short   toshort()       { return (short) v; }
 | 
			
		||||
 | 
			
		||||
	public double      optdouble(double defval)            { return v; }
 | 
			
		||||
	public int         optint(int defval)                  { return v;  }
 | 
			
		||||
	public LuaInteger  optinteger(LuaInteger defval)       { return this; }
 | 
			
		||||
	public long        optlong(long defval)                { return v; }
 | 
			
		||||
 | 
			
		||||
	public String tojstring() {
 | 
			
		||||
		return Integer.toString(v);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaString strvalue() {
 | 
			
		||||
		return LuaString.valueOf(Integer.toString(v));
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
	public LuaString optstring(LuaString defval) {
 | 
			
		||||
		return LuaString.valueOf(Integer.toString(v)); 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue tostring() {
 | 
			
		||||
		return LuaString.valueOf(Integer.toString(v)); 
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
	public String optjstring(String defval) { 
 | 
			
		||||
		return Integer.toString(v); 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaInteger checkinteger() {
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isstring() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int hashCode() {
 | 
			
		||||
		return v;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// unary operators
 | 
			
		||||
	public LuaValue neg() { return valueOf(-(long)v); }
 | 
			
		||||
	
 | 
			
		||||
	// object equality, used for key comparison
 | 
			
		||||
	public boolean equals(Object o) { return o instanceof LuaInteger? ((LuaInteger)o).v == v: false; }
 | 
			
		||||
	
 | 
			
		||||
	// equality w/ metatable processing
 | 
			
		||||
	public LuaValue eq( LuaValue val )    { return val.raweq(v)? TRUE: FALSE; }
 | 
			
		||||
	public boolean eq_b( LuaValue val )   { return val.raweq(v); }
 | 
			
		||||
	
 | 
			
		||||
	// equality w/o metatable processing
 | 
			
		||||
	public boolean raweq( LuaValue val )  { return val.raweq(v); }
 | 
			
		||||
	public boolean raweq( double val )    { return v == val; }
 | 
			
		||||
	public boolean raweq( int val )       { return v == val; }
 | 
			
		||||
	
 | 
			
		||||
	// arithmetic operators
 | 
			
		||||
	public LuaValue   add( LuaValue rhs )        { return rhs.add(v); }
 | 
			
		||||
	public LuaValue   add( double lhs )     { return LuaDouble.valueOf(lhs + v); }
 | 
			
		||||
	public LuaValue   add( int lhs )        { return LuaInteger.valueOf(lhs + (long)v); }
 | 
			
		||||
	public LuaValue   sub( LuaValue rhs )        { return rhs.subFrom(v); }
 | 
			
		||||
	public LuaValue   sub( double rhs )        { return LuaDouble.valueOf(v - rhs); }
 | 
			
		||||
	public LuaValue   sub( int rhs )        { return LuaDouble.valueOf(v - rhs); }
 | 
			
		||||
	public LuaValue   subFrom( double lhs )   { return LuaDouble.valueOf(lhs - v); }
 | 
			
		||||
	public LuaValue   subFrom( int lhs )      { return LuaInteger.valueOf(lhs - (long)v); }
 | 
			
		||||
	public LuaValue   mul( LuaValue rhs )        { return rhs.mul(v); }
 | 
			
		||||
	public LuaValue   mul( double lhs )   { return LuaDouble.valueOf(lhs * v); }
 | 
			
		||||
	public LuaValue   mul( int lhs )      { return LuaInteger.valueOf(lhs * (long)v); }
 | 
			
		||||
	public LuaValue   pow( LuaValue rhs )        { return rhs.powWith(v); }
 | 
			
		||||
	public LuaValue   pow( double rhs )        { return MathLib.dpow(v,rhs); }
 | 
			
		||||
	public LuaValue   pow( int rhs )        { return MathLib.dpow(v,rhs); }
 | 
			
		||||
	public LuaValue   powWith( double lhs )   { return MathLib.dpow(lhs,v); }
 | 
			
		||||
	public LuaValue   powWith( int lhs )      { return MathLib.dpow(lhs,v); }
 | 
			
		||||
	public LuaValue   div( LuaValue rhs )        { return rhs.divInto(v); }
 | 
			
		||||
	public LuaValue   div( double rhs )        { return LuaDouble.ddiv(v,rhs); }
 | 
			
		||||
	public LuaValue   div( int rhs )        { return LuaDouble.ddiv(v,rhs); }
 | 
			
		||||
	public LuaValue   divInto( double lhs )   { return LuaDouble.ddiv(lhs,v); }
 | 
			
		||||
	public LuaValue   mod( LuaValue rhs )        { return rhs.modFrom(v); }
 | 
			
		||||
	public LuaValue   mod( double rhs )        { return LuaDouble.dmod(v,rhs); }
 | 
			
		||||
	public LuaValue   mod( int rhs )        { return LuaDouble.dmod(v,rhs); }
 | 
			
		||||
	public LuaValue   modFrom( double lhs )   { return LuaDouble.dmod(lhs,v); }
 | 
			
		||||
	
 | 
			
		||||
	// relational operators
 | 
			
		||||
	public LuaValue   lt( LuaValue rhs )         { return rhs.gt_b(v)? TRUE: FALSE; }	
 | 
			
		||||
	public LuaValue   lt( double rhs )      { return v < rhs? TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   lt( int rhs )         { return v < rhs? TRUE: FALSE; }
 | 
			
		||||
	public boolean lt_b( LuaValue rhs )       { return rhs.gt_b(v); }
 | 
			
		||||
	public boolean lt_b( int rhs )         { return v < rhs; }
 | 
			
		||||
	public boolean lt_b( double rhs )      { return v < rhs; }
 | 
			
		||||
	public LuaValue   lteq( LuaValue rhs )       { return rhs.gteq_b(v)? TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   lteq( double rhs )    { return v <= rhs? TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   lteq( int rhs )       { return v <= rhs? TRUE: FALSE; }
 | 
			
		||||
	public boolean lteq_b( LuaValue rhs )     { return rhs.gteq_b(v); }
 | 
			
		||||
	public boolean lteq_b( int rhs )       { return v <= rhs; }
 | 
			
		||||
	public boolean lteq_b( double rhs )    { return v <= rhs; }
 | 
			
		||||
	public LuaValue   gt( LuaValue rhs )         { return rhs.lt_b(v)? TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   gt( double rhs )      { return v > rhs? TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   gt( int rhs )         { return v > rhs? TRUE: FALSE; }
 | 
			
		||||
	public boolean gt_b( LuaValue rhs )       { return rhs.lt_b(v); }
 | 
			
		||||
	public boolean gt_b( int rhs )         { return v > rhs; }
 | 
			
		||||
	public boolean gt_b( double rhs )      { return v > rhs; }
 | 
			
		||||
	public LuaValue   gteq( LuaValue rhs )       { return rhs.lteq_b(v)? TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   gteq( double rhs )    { return v >= rhs? TRUE: FALSE; }
 | 
			
		||||
	public LuaValue   gteq( int rhs )       { return v >= rhs? TRUE: FALSE; }
 | 
			
		||||
	public boolean gteq_b( LuaValue rhs )     { return rhs.lteq_b(v); }
 | 
			
		||||
	public boolean gteq_b( int rhs )       { return v >= rhs; }
 | 
			
		||||
	public boolean gteq_b( double rhs )    { return v >= rhs; }
 | 
			
		||||
	
 | 
			
		||||
	// string comparison
 | 
			
		||||
	public int strcmp( LuaString rhs )      { typerror("attempt to compare number with string"); return 0; }
 | 
			
		||||
	
 | 
			
		||||
	public int checkint() { 
 | 
			
		||||
		return v; 
 | 
			
		||||
	}
 | 
			
		||||
	public long checklong() {
 | 
			
		||||
		return v; 
 | 
			
		||||
	}
 | 
			
		||||
	public double checkdouble() {
 | 
			
		||||
		return v;
 | 
			
		||||
	}
 | 
			
		||||
	public String checkjstring() { 
 | 
			
		||||
		return String.valueOf(v); 
 | 
			
		||||
	}
 | 
			
		||||
	public LuaString checkstring() { 
 | 
			
		||||
		return valueOf( String.valueOf(v) ); 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,104 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class to encapsulate behavior of the singleton instance {@code nil} 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * There will be one instance of this class, {@link LuaValue#NIL}, 
 | 
			
		||||
 * per Java virtual machine.  
 | 
			
		||||
 * However, the {@link Varargs} instance {@link LuaValue#NONE}
 | 
			
		||||
 * which is the empty list, 
 | 
			
		||||
 * is also considered treated as a nil value by default.  
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Although it is possible to test for nil using Java == operator, 
 | 
			
		||||
 * the recommended approach is to use the method {@link LuaValue#isnil()} 
 | 
			
		||||
 * instead.  By using that any ambiguities between 
 | 
			
		||||
 * {@link LuaValue#NIL} and {@link LuaValue#NONE} are avoided.
 | 
			
		||||
 * @see LuaValue
 | 
			
		||||
 * @see LuaValue#NIL
 | 
			
		||||
 */
 | 
			
		||||
public class LuaNil extends LuaValue {
 | 
			
		||||
	
 | 
			
		||||
	static final LuaNil _NIL = new LuaNil();
 | 
			
		||||
	
 | 
			
		||||
	public static LuaValue s_metatable;
 | 
			
		||||
	
 | 
			
		||||
	LuaNil() {}
 | 
			
		||||
 | 
			
		||||
	public int type() {
 | 
			
		||||
		return LuaValue.TNIL;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public String typename() {
 | 
			
		||||
		return "nil";
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public String tojstring() {
 | 
			
		||||
		return "nil";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue not()  { 
 | 
			
		||||
		return LuaValue.TRUE;  
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean toboolean() { 
 | 
			
		||||
		return false; 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isnil() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
	public LuaValue getmetatable() { 
 | 
			
		||||
		return s_metatable; 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean equals(Object o) {
 | 
			
		||||
		return o instanceof LuaNil;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue checknotnil() { 
 | 
			
		||||
		return argerror("value");
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue checkvalidkey() {
 | 
			
		||||
		return typerror("table index"); 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// optional argument conversions - nil alwas falls badk to default value
 | 
			
		||||
	public boolean     optboolean(boolean defval)          { return defval; }
 | 
			
		||||
	public LuaClosure  optclosure(LuaClosure defval)       { return defval; }
 | 
			
		||||
	public double      optdouble(double defval)               { return defval; }
 | 
			
		||||
	public LuaFunction optfunction(LuaFunction defval)     { return defval; }
 | 
			
		||||
	public int         optint(int defval)                  { return defval; }
 | 
			
		||||
	public LuaInteger  optinteger(LuaInteger defval)       { return defval; }
 | 
			
		||||
	public long        optlong(long defval)                { return defval; }
 | 
			
		||||
	public LuaNumber   optnumber(LuaNumber defval)         { return defval; }
 | 
			
		||||
	public LuaTable    opttable(LuaTable defval)           { return defval; }
 | 
			
		||||
	public LuaThread   optthread(LuaThread defval)         { return defval; }
 | 
			
		||||
	public String      optjstring(String defval)            { return defval; }
 | 
			
		||||
	public LuaString   optstring(LuaString defval)         { return defval; }
 | 
			
		||||
	public Object      optuserdata(Object defval)          { return defval; }
 | 
			
		||||
	public Object      optuserdata(Class c, Object defval) { return defval; }
 | 
			
		||||
	public LuaValue    optvalue(LuaValue defval)           { return defval; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,81 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Base class for representing numbers as lua values directly. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The main subclasses are {@link LuaInteger} which holds values that fit in a java int, 
 | 
			
		||||
 * and {@link LuaDouble} which holds all other number values.
 | 
			
		||||
 * @see LuaInteger
 | 
			
		||||
 * @see LuaDouble
 | 
			
		||||
 * @see LuaValue
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
abstract
 | 
			
		||||
public class LuaNumber extends LuaValue {
 | 
			
		||||
 | 
			
		||||
	/** Shared static metatable for all number values represented in lua. */
 | 
			
		||||
	public static LuaValue s_metatable;
 | 
			
		||||
	
 | 
			
		||||
	public int type() {
 | 
			
		||||
		return TNUMBER;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public String typename() {
 | 
			
		||||
		return "number";
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaNumber checknumber() {
 | 
			
		||||
		return this; 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaNumber checknumber(String errmsg) {
 | 
			
		||||
		return this; 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaNumber optnumber(LuaNumber defval) {
 | 
			
		||||
		return this; 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue tonumber() {
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isnumber() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isstring() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue getmetatable() { 
 | 
			
		||||
		return s_metatable; 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue concat(LuaValue rhs)      { return rhs.concatTo(this); }
 | 
			
		||||
	public Buffer   concat(Buffer rhs)        { return rhs.concatTo(this); }
 | 
			
		||||
	public LuaValue concatTo(LuaNumber lhs)   { return strvalue().concatTo(lhs.strvalue()); }
 | 
			
		||||
	public LuaValue concatTo(LuaString lhs)   { return strvalue().concatTo(lhs); }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,749 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import java.io.ByteArrayInputStream;
 | 
			
		||||
import java.io.DataOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.lang.String;
 | 
			
		||||
import java.lang.ref.WeakReference;
 | 
			
		||||
import java.util.Hashtable;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.lib.MathLib;
 | 
			
		||||
import org.luaj.vm2.lib.StringLib;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Subclass of {@link LuaValue} for representing lua strings. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Because lua string values are more nearly sequences of bytes than 
 | 
			
		||||
 * sequences of characters or unicode code points, the {@link LuaString}
 | 
			
		||||
 * implementation holds the string value in an internal byte array.  
 | 
			
		||||
 * <p>
 | 
			
		||||
 * {@link LuaString} values are generally not mutable once constructed, 
 | 
			
		||||
 * so multiple {@link LuaString} values can chare a single byte array.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Currently {@link LuaString}s are pooled via a centrally managed weak table.
 | 
			
		||||
 * To ensure that as many string values as possible take advantage of this, 
 | 
			
		||||
 * Constructors are not exposed directly.  As with number, booleans, and nil, 
 | 
			
		||||
 * instance construction should be via {@link LuaValue#valueOf(byte[])} or similar API.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * When Java Strings are used to initialize {@link LuaString} data, the UTF8 encoding is assumed. 
 | 
			
		||||
 * The functions 
 | 
			
		||||
 * {@link LuaString#lengthAsUtf8(char[]),
 | 
			
		||||
 * {@link LuaString#encodeToUtf8(char[], byte[], int)}, and 
 | 
			
		||||
 * {@link LuaString#decodeAsUtf8(byte[], int, int) 
 | 
			
		||||
 * are used to convert back and forth between UTF8 byte arrays and character arrays.
 | 
			
		||||
 * 
 | 
			
		||||
 * @see LuaValue
 | 
			
		||||
 * @see LuaValue#valueOf(String)
 | 
			
		||||
 * @see LuaValue#valueOf(byte[])
 | 
			
		||||
 */
 | 
			
		||||
public class LuaString extends LuaValue {
 | 
			
		||||
 | 
			
		||||
	/** The singleton instance representing lua {@code true} */
 | 
			
		||||
	public static LuaValue s_metatable;
 | 
			
		||||
 | 
			
		||||
	/** The bytes for the string */
 | 
			
		||||
	public final byte[] m_bytes;
 | 
			
		||||
	
 | 
			
		||||
	/** The offset into the byte array, 0 means start at the first byte */
 | 
			
		||||
	public final int    m_offset;
 | 
			
		||||
	
 | 
			
		||||
	/** The number of bytes that comprise this string */
 | 
			
		||||
	public final int    m_length;
 | 
			
		||||
 | 
			
		||||
	private static final Hashtable index_java = new Hashtable();
 | 
			
		||||
 | 
			
		||||
	private final static LuaString index_get(Hashtable indextable, Object key) {
 | 
			
		||||
		WeakReference w = (WeakReference) indextable.get(key);
 | 
			
		||||
		return w!=null? (LuaString) w.get(): null;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private final static void index_set(Hashtable indextable, Object key, LuaString value) {
 | 
			
		||||
		indextable.put(key, new WeakReference(value));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get a {@link LuaString} instance whose bytes match 
 | 
			
		||||
	 * the supplied Java String using the UTF8 encoding. 
 | 
			
		||||
	 * @param string Java String containing characters to encode as UTF8
 | 
			
		||||
	 * @return {@link LuaString} with UTF8 bytes corresponding to the supplied String
 | 
			
		||||
	 */
 | 
			
		||||
	public static LuaString valueOf(String string) {
 | 
			
		||||
		LuaString s = index_get( index_java, string );
 | 
			
		||||
		if ( s != null ) return s;
 | 
			
		||||
		char[] c = string.toCharArray();
 | 
			
		||||
        /* DAN200 START */
 | 
			
		||||
        /*
 | 
			
		||||
		byte[] b = new byte[lengthAsUtf8(c)];
 | 
			
		||||
		encodeToUtf8(c, b, 0);
 | 
			
		||||
		*/
 | 
			
		||||
        byte[] b = new byte[c.length];
 | 
			
		||||
        for( int i=0; i<b.length; ++i )
 | 
			
		||||
        {
 | 
			
		||||
            char ch = c[i];
 | 
			
		||||
            b[i] = (ch < 256) ? (byte)ch : (byte)'?';
 | 
			
		||||
        }
 | 
			
		||||
        /* DAN200 END */
 | 
			
		||||
		s = valueOf(b, 0, b.length);
 | 
			
		||||
		index_set( index_java, string, s );
 | 
			
		||||
		return s;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// TODO: should this be deprecated or made private?
 | 
			
		||||
	/** Construct a {@link LuaString} around a byte array without copying the contents.
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * The array is used directly after this is called, so clients must not change contents.
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * @param bytes byte buffer
 | 
			
		||||
	 * @param off offset into the byte buffer
 | 
			
		||||
	 * @param len length of the byte buffer
 | 
			
		||||
	 * @return {@link LuaString} wrapping the byte buffer
 | 
			
		||||
	 */
 | 
			
		||||
	public static LuaString valueOf(byte[] bytes, int off, int len) { 
 | 
			
		||||
		return new LuaString(bytes, off, len);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Construct a {@link LuaString} using the supplied characters as byte values.
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Only th elow-order 8-bits of each character are used, the remainder is ignored. 
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * This is most useful for constructing byte sequences that do not conform to UTF8. 
 | 
			
		||||
	 * @param bytes array of char, whose values are truncated at 8-bits each and put into a byte array. 
 | 
			
		||||
	 * @return {@link LuaString} wrapping a copy of the byte buffer 
 | 
			
		||||
	 */
 | 
			
		||||
	public static LuaString valueOf(char[] bytes) {
 | 
			
		||||
		int n = bytes.length;
 | 
			
		||||
		byte[] b = new byte[n];
 | 
			
		||||
		for ( int i=0; i<n; i++ )
 | 
			
		||||
			b[i] = (byte) bytes[i];
 | 
			
		||||
		return valueOf(b, 0, n);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	/** Construct a {@link LuaString} around a byte array without copying the contents.
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * The array is used directly after this is called, so clients must not change contents.
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * @param bytes byte buffer
 | 
			
		||||
	 * @return {@link LuaString} wrapping the byte buffer
 | 
			
		||||
	 */
 | 
			
		||||
	public static LuaString valueOf(byte[] bytes) {
 | 
			
		||||
		return valueOf(bytes, 0, bytes.length);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Construct a {@link LuaString} around a byte array without copying the contents.
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * The array is used directly after this is called, so clients must not change contents.
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * @param bytes byte buffer
 | 
			
		||||
	 * @param offset offset into the byte buffer
 | 
			
		||||
	 * @param length length of the byte buffer
 | 
			
		||||
	 * @return {@link LuaString} wrapping the byte buffer
 | 
			
		||||
	 */
 | 
			
		||||
	private LuaString(byte[] bytes, int offset, int length) {
 | 
			
		||||
		this.m_bytes = bytes;
 | 
			
		||||
		this.m_offset = offset;
 | 
			
		||||
		this.m_length = length;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isstring() {
 | 
			
		||||
		return true; 
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
	public LuaValue getmetatable() { 
 | 
			
		||||
		return s_metatable; 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int type() {
 | 
			
		||||
		return LuaValue.TSTRING;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String typename() {
 | 
			
		||||
		return "string";
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public String tojstring() {
 | 
			
		||||
        /* DAN200 START */
 | 
			
		||||
		/*
 | 
			
		||||
		return decodeAsUtf8(m_bytes, m_offset, m_length);
 | 
			
		||||
		*/
 | 
			
		||||
        char[] chars = new char[ m_length ];
 | 
			
		||||
        for( int i=0; i<chars.length; ++i )
 | 
			
		||||
        {
 | 
			
		||||
            chars[i] = (char)(m_bytes[ m_offset + i ] & 255);
 | 
			
		||||
        }
 | 
			
		||||
        return new String( chars );
 | 
			
		||||
        /* DAN200 END */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// get is delegated to the string library
 | 
			
		||||
	public LuaValue get(LuaValue key) {
 | 
			
		||||
		return s_metatable!=null? gettable(this,key): StringLib.instance.get(key);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// unary operators
 | 
			
		||||
	public LuaValue neg() { double d = scannumber(10); return Double.isNaN(d)? super.neg(): valueOf(-d); }
 | 
			
		||||
 | 
			
		||||
	// basic binary arithmetic
 | 
			
		||||
	public LuaValue   add( LuaValue rhs )      { double d = scannumber(10); return Double.isNaN(d)? arithmt(ADD,rhs): rhs.add(d); }
 | 
			
		||||
	public LuaValue   add( double rhs )        { return valueOf( checkarith() + rhs ); }
 | 
			
		||||
	public LuaValue   add( int rhs )           { return valueOf( checkarith() + rhs ); }
 | 
			
		||||
	public LuaValue   sub( LuaValue rhs )      { double d = scannumber(10); return Double.isNaN(d)? arithmt(SUB,rhs): rhs.subFrom(d); }
 | 
			
		||||
	public LuaValue   sub( double rhs )        { return valueOf( checkarith() - rhs ); }
 | 
			
		||||
	public LuaValue   sub( int rhs )           { return valueOf( checkarith() - rhs ); }
 | 
			
		||||
	public LuaValue   subFrom( double lhs )    { return valueOf( lhs - checkarith() ); }
 | 
			
		||||
	public LuaValue   mul( LuaValue rhs )      { double d = scannumber(10); return Double.isNaN(d)? arithmt(MUL,rhs): rhs.mul(d); }
 | 
			
		||||
	public LuaValue   mul( double rhs )        { return valueOf( checkarith() * rhs ); }
 | 
			
		||||
	public LuaValue   mul( int rhs )           { return valueOf( checkarith() * rhs ); }
 | 
			
		||||
	public LuaValue   pow( LuaValue rhs )      { double d = scannumber(10); return Double.isNaN(d)? arithmt(POW,rhs): rhs.powWith(d); }
 | 
			
		||||
	public LuaValue   pow( double rhs )        { return MathLib.dpow(checkarith(),rhs); }
 | 
			
		||||
	public LuaValue   pow( int rhs )           { return MathLib.dpow(checkarith(),rhs); }
 | 
			
		||||
	public LuaValue   powWith( double lhs )    { return MathLib.dpow(lhs, checkarith()); }
 | 
			
		||||
	public LuaValue   powWith( int lhs )       { return MathLib.dpow(lhs, checkarith()); }
 | 
			
		||||
	public LuaValue   div( LuaValue rhs )      { double d = scannumber(10); return Double.isNaN(d)? arithmt(DIV,rhs): rhs.divInto(d); }
 | 
			
		||||
	public LuaValue   div( double rhs )        { return LuaDouble.ddiv(checkarith(),rhs); }
 | 
			
		||||
	public LuaValue   div( int rhs )           { return LuaDouble.ddiv(checkarith(),rhs); }
 | 
			
		||||
	public LuaValue   divInto( double lhs )    { return LuaDouble.ddiv(lhs, checkarith()); }
 | 
			
		||||
	public LuaValue   mod( LuaValue rhs )      { double d = scannumber(10); return Double.isNaN(d)? arithmt(MOD,rhs): rhs.modFrom(d); }
 | 
			
		||||
	public LuaValue   mod( double rhs )        { return LuaDouble.dmod(checkarith(), rhs); }
 | 
			
		||||
	public LuaValue   mod( int rhs )           { return LuaDouble.dmod(checkarith(), rhs); }
 | 
			
		||||
	public LuaValue   modFrom( double lhs )    { return LuaDouble.dmod(lhs, checkarith()); }
 | 
			
		||||
	
 | 
			
		||||
	// relational operators, these only work with other strings
 | 
			
		||||
	public LuaValue   lt( LuaValue rhs )         { return rhs.strcmp(this)>0? LuaValue.TRUE: FALSE; }
 | 
			
		||||
	public boolean lt_b( LuaValue rhs )       { return rhs.strcmp(this)>0; }
 | 
			
		||||
	public boolean lt_b( int rhs )         { typerror("attempt to compare string with number"); return false; }
 | 
			
		||||
	public boolean lt_b( double rhs )      { typerror("attempt to compare string with number"); return false; }
 | 
			
		||||
	public LuaValue   lteq( LuaValue rhs )       { return rhs.strcmp(this)>=0? LuaValue.TRUE: FALSE; }
 | 
			
		||||
	public boolean lteq_b( LuaValue rhs )     { return rhs.strcmp(this)>=0; }
 | 
			
		||||
	public boolean lteq_b( int rhs )       { typerror("attempt to compare string with number"); return false; }
 | 
			
		||||
	public boolean lteq_b( double rhs )    { typerror("attempt to compare string with number"); return false; }
 | 
			
		||||
	public LuaValue   gt( LuaValue rhs )         { return rhs.strcmp(this)<0? LuaValue.TRUE: FALSE; }
 | 
			
		||||
	public boolean gt_b( LuaValue rhs )       { return rhs.strcmp(this)<0; }
 | 
			
		||||
	public boolean gt_b( int rhs )         { typerror("attempt to compare string with number"); return false; }
 | 
			
		||||
	public boolean gt_b( double rhs )      { typerror("attempt to compare string with number"); return false; }
 | 
			
		||||
	public LuaValue   gteq( LuaValue rhs )       { return rhs.strcmp(this)<=0? LuaValue.TRUE: FALSE; }
 | 
			
		||||
	public boolean gteq_b( LuaValue rhs )     { return rhs.strcmp(this)<=0; }
 | 
			
		||||
	public boolean gteq_b( int rhs )       { typerror("attempt to compare string with number"); return false; }
 | 
			
		||||
	public boolean gteq_b( double rhs )    { typerror("attempt to compare string with number"); return false; }
 | 
			
		||||
 | 
			
		||||
	// concatenation
 | 
			
		||||
	public LuaValue concat(LuaValue rhs)      { return rhs.concatTo(this); }
 | 
			
		||||
	public Buffer   concat(Buffer rhs)        { return rhs.concatTo(this); }
 | 
			
		||||
	public LuaValue concatTo(LuaNumber lhs)   { return concatTo(lhs.strvalue()); }
 | 
			
		||||
	public LuaValue concatTo(LuaString lhs)   { 
 | 
			
		||||
		byte[] b = new byte[lhs.m_length+this.m_length];
 | 
			
		||||
		System.arraycopy(lhs.m_bytes, lhs.m_offset, b, 0, lhs.m_length);
 | 
			
		||||
		System.arraycopy(this.m_bytes, this.m_offset, b, lhs.m_length, this.m_length);
 | 
			
		||||
		return new LuaString(b, 0, b.length);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// string comparison 
 | 
			
		||||
	public int strcmp(LuaValue lhs)           { return -lhs.strcmp(this); }
 | 
			
		||||
	public int strcmp(LuaString rhs) {
 | 
			
		||||
		for ( int i=0, j=0; i<m_length && j<rhs.m_length; ++i, ++j ) {
 | 
			
		||||
			if ( m_bytes[m_offset+i] != rhs.m_bytes[rhs.m_offset+j] ) {
 | 
			
		||||
				return ((int)m_bytes[m_offset+i]) - ((int) rhs.m_bytes[rhs.m_offset+j]);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return m_length - rhs.m_length;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Check for number in arithmetic, or throw aritherror */
 | 
			
		||||
	private double checkarith() { 
 | 
			
		||||
		double d = scannumber(10);
 | 
			
		||||
		if ( Double.isNaN(d) ) 
 | 
			
		||||
			aritherror();
 | 
			
		||||
		return d;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int checkint() {
 | 
			
		||||
		return (int) (long) checkdouble();
 | 
			
		||||
	}
 | 
			
		||||
	public LuaInteger checkinteger() {
 | 
			
		||||
		return valueOf(checkint());
 | 
			
		||||
	}
 | 
			
		||||
	public long checklong() {
 | 
			
		||||
		return (long) checkdouble();
 | 
			
		||||
	}
 | 
			
		||||
	public double checkdouble() {
 | 
			
		||||
		double d = scannumber(10);
 | 
			
		||||
		if ( Double.isNaN(d) )
 | 
			
		||||
			argerror("number");
 | 
			
		||||
		return d;
 | 
			
		||||
	}
 | 
			
		||||
	public LuaNumber checknumber() {
 | 
			
		||||
		return valueOf(checkdouble());
 | 
			
		||||
	}
 | 
			
		||||
	public LuaNumber checknumber(String msg) {
 | 
			
		||||
		double d = scannumber(10);
 | 
			
		||||
		if ( Double.isNaN(d) )
 | 
			
		||||
			error(msg);
 | 
			
		||||
		return valueOf(d);
 | 
			
		||||
	}
 | 
			
		||||
	public LuaValue tonumber() {
 | 
			
		||||
		return tonumber(10);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isnumber() {
 | 
			
		||||
		double d = scannumber(10);
 | 
			
		||||
		return ! Double.isNaN(d);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isint() {
 | 
			
		||||
		double d = scannumber(10);
 | 
			
		||||
		if ( Double.isNaN(d) ) 
 | 
			
		||||
			return false;
 | 
			
		||||
		int i = (int) d;
 | 
			
		||||
		return i == d;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean islong() { 
 | 
			
		||||
		double d = scannumber(10);
 | 
			
		||||
		if ( Double.isNaN(d) ) 
 | 
			
		||||
			return false;
 | 
			
		||||
		long l = (long) d;
 | 
			
		||||
		return l == d;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public byte    tobyte()        { return (byte) toint(); }
 | 
			
		||||
	public char    tochar()        { return (char) toint(); }
 | 
			
		||||
	public double  todouble()      { double d=scannumber(10); return Double.isNaN(d)? 0: d; }
 | 
			
		||||
	public float   tofloat()       { return (float) todouble(); }
 | 
			
		||||
	public int     toint()         { return (int) tolong(); }
 | 
			
		||||
	public long    tolong()        { return (long) todouble(); }
 | 
			
		||||
	public short   toshort()       { return (short) toint(); }
 | 
			
		||||
 | 
			
		||||
	public double optdouble(double defval) {
 | 
			
		||||
		return checknumber().checkdouble();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int optint(int defval) {
 | 
			
		||||
		return checknumber().checkint();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaInteger optinteger(LuaInteger defval) { 
 | 
			
		||||
		return checknumber().checkinteger();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public long optlong(long defval) {
 | 
			
		||||
		return checknumber().checklong();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaNumber optnumber(LuaNumber defval) {
 | 
			
		||||
		return checknumber().checknumber();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaString optstring(LuaString defval) {
 | 
			
		||||
		return this; 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue tostring() {
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String optjstring(String defval) { 
 | 
			
		||||
		return tojstring(); 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaString strvalue() {
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaString substring( int beginIndex, int endIndex ) {
 | 
			
		||||
		return new LuaString( m_bytes, m_offset + beginIndex, endIndex - beginIndex );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int hashCode() {
 | 
			
		||||
		int h = m_length;  /* seed */
 | 
			
		||||
		int step = (m_length>>5)+1;  /* if string is too long, don't hash all its chars */
 | 
			
		||||
		for (int l1=m_length; l1>=step; l1-=step)  /* compute hash */
 | 
			
		||||
		    h = h ^ ((h<<5)+(h>>2)+(((int) m_bytes[m_offset+l1-1] ) & 0x0FF ));
 | 
			
		||||
		return h;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// object comparison, used in key comparison
 | 
			
		||||
	public boolean equals( Object o ) {
 | 
			
		||||
		if ( o instanceof LuaString ) {
 | 
			
		||||
			return raweq( (LuaString) o );
 | 
			
		||||
		}
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// equality w/ metatable processing
 | 
			
		||||
	public LuaValue eq( LuaValue val )    { return val.raweq(this)? TRUE: FALSE; }
 | 
			
		||||
	public boolean eq_b( LuaValue val )   { return val.raweq(this); }
 | 
			
		||||
	
 | 
			
		||||
	// equality w/o metatable processing
 | 
			
		||||
	public boolean raweq( LuaValue val ) {
 | 
			
		||||
		return val.raweq(this);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean raweq( LuaString s ) { 
 | 
			
		||||
		if ( this == s )
 | 
			
		||||
			return true;
 | 
			
		||||
		if ( s.m_length != m_length )
 | 
			
		||||
			return false;
 | 
			
		||||
		if ( s.m_bytes == m_bytes && s.m_offset == m_offset )
 | 
			
		||||
			return true;
 | 
			
		||||
		if ( s.hashCode() != hashCode() )
 | 
			
		||||
			return false;
 | 
			
		||||
		for ( int i=0; i<m_length; i++ )
 | 
			
		||||
			if ( s.m_bytes[s.m_offset+i] != m_bytes[m_offset+i] )
 | 
			
		||||
				return false;
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static boolean equals( LuaString a, int i, LuaString b, int j, int n ) {
 | 
			
		||||
		return equals( a.m_bytes, a.m_offset + i, b.m_bytes, b.m_offset + j, n );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static boolean equals( byte[] a, int i, byte[] b, int j, int n ) {
 | 
			
		||||
		if ( a.length < i + n || b.length < j + n )
 | 
			
		||||
			return false;
 | 
			
		||||
		while ( --n>=0 ) 
 | 
			
		||||
			if ( a[i++]!=b[j++] )
 | 
			
		||||
				return false;
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void write(DataOutputStream writer, int i, int len) throws IOException {
 | 
			
		||||
		writer.write(m_bytes,m_offset+i,len);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue len() {
 | 
			
		||||
		return LuaInteger.valueOf(m_length);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int length() {
 | 
			
		||||
		return m_length;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int luaByte(int index) {
 | 
			
		||||
		return m_bytes[m_offset + index] & 0x0FF;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int charAt( int index ) {
 | 
			
		||||
		if ( index < 0 || index >= m_length )
 | 
			
		||||
			throw new IndexOutOfBoundsException();
 | 
			
		||||
		return luaByte( index );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public String checkjstring() { 
 | 
			
		||||
		return tojstring(); 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaString checkstring() {
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Convert value to an input stream.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @return {@link InputStream} whose data matches the bytes in this {@link LuaString}
 | 
			
		||||
	 */
 | 
			
		||||
	public InputStream toInputStream() {
 | 
			
		||||
		return new ByteArrayInputStream(m_bytes, m_offset, m_length);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Copy the bytes of the string into the given byte array. 
 | 
			
		||||
	 * @param strOffset offset from which to copy
 | 
			
		||||
	 * @param bytes destination byte array
 | 
			
		||||
	 * @param arrayOffset offset in destination
 | 
			
		||||
	 * @param len number of bytes to copy
 | 
			
		||||
	 */
 | 
			
		||||
	public void copyInto( int strOffset, byte[] bytes, int arrayOffset, int len ) {
 | 
			
		||||
		System.arraycopy( m_bytes, m_offset+strOffset, bytes, arrayOffset, len );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Java version of strpbrk - find index of any byte that in an accept string.
 | 
			
		||||
	 * @param accept {@link LuaString} containing characters to look for.
 | 
			
		||||
	 * @return index of first match in the {@code accept} string, or -1 if not found.
 | 
			
		||||
	 */
 | 
			
		||||
	public int indexOfAny( LuaString accept ) {
 | 
			
		||||
		final int ilimit = m_offset + m_length;
 | 
			
		||||
		final int jlimit = accept.m_offset + accept.m_length;
 | 
			
		||||
		for ( int i = m_offset; i < ilimit; ++i ) {
 | 
			
		||||
			for ( int j = accept.m_offset; j < jlimit; ++j ) {
 | 
			
		||||
				if ( m_bytes[i] == accept.m_bytes[j] ) {
 | 
			
		||||
					return i - m_offset;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Find the index of a byte starting at a point in this string
 | 
			
		||||
	 * @param b the byte to look for
 | 
			
		||||
	 * @param start the first index in the string
 | 
			
		||||
	 * @return index of first match found, or -1 if not found.
 | 
			
		||||
	 */
 | 
			
		||||
	public int indexOf( byte b, int start ) {
 | 
			
		||||
		for ( int i=0, j=m_offset+start; i < m_length; ++i ) {
 | 
			
		||||
			if ( m_bytes[j++] == b )
 | 
			
		||||
				return i;
 | 
			
		||||
		}
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Find the index of a string starting at a point in this string
 | 
			
		||||
	 * @param s the string to search for
 | 
			
		||||
	 * @param start the first index in the string
 | 
			
		||||
	 * @return index of first match found, or -1 if not found.
 | 
			
		||||
	 */
 | 
			
		||||
	public int indexOf( LuaString s, int start ) {
 | 
			
		||||
		final int slen = s.length();
 | 
			
		||||
		final int limit = m_offset + m_length - slen;
 | 
			
		||||
		for ( int i = m_offset + start; i <= limit; ++i ) {
 | 
			
		||||
			if ( equals( m_bytes, i, s.m_bytes, s.m_offset, slen ) ) {
 | 
			
		||||
				/* DAN200 START */
 | 
			
		||||
				//return i;
 | 
			
		||||
				return i - m_offset;
 | 
			
		||||
				/* DAN200 END */
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Find the last index of a string in this string
 | 
			
		||||
	 * @param s the string to search for
 | 
			
		||||
	 * @return index of last match found, or -1 if not found.
 | 
			
		||||
	 */
 | 
			
		||||
	public int lastIndexOf( LuaString s ) {
 | 
			
		||||
		final int slen = s.length();
 | 
			
		||||
		final int limit = m_offset + m_length - slen;
 | 
			
		||||
		for ( int i = limit; i >= m_offset; --i ) {
 | 
			
		||||
			if ( equals( m_bytes, i, s.m_bytes, s.m_offset, slen ) ) {
 | 
			
		||||
				/* DAN200 START */
 | 
			
		||||
				//return i;
 | 
			
		||||
				return i - m_offset;
 | 
			
		||||
				/* DAN200 END */
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Convert to Java String interpreting as utf8 characters. 
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param bytes byte array in UTF8 encoding to convert
 | 
			
		||||
	 * @param offset starting index in byte array
 | 
			
		||||
	 * @param length number of bytes to convert
 | 
			
		||||
	 * @return Java String corresponding to the value of bytes interpreted using UTF8 
 | 
			
		||||
	 * @see #lengthAsUtf8(char[])
 | 
			
		||||
	 * @see #encodeToUtf8(char[], byte[], int)
 | 
			
		||||
	 * @see #isValidUtf8()
 | 
			
		||||
	 */
 | 
			
		||||
	/* DAN200 START */
 | 
			
		||||
	//public static String decodeAsUtf8(byte[] bytes, int offset, int length) {
 | 
			
		||||
	private static String decodeAsUtf8(byte[] bytes, int offset, int length) {
 | 
			
		||||
	/* DAN200 END */
 | 
			
		||||
		int i,j,n,b;
 | 
			
		||||
		for ( i=offset,j=offset+length,n=0; i<j; ++n ) {
 | 
			
		||||
			switch ( 0xE0 & bytes[i++] ) {
 | 
			
		||||
			case 0xE0: ++i;
 | 
			
		||||
			case 0xC0: ++i;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		char[] chars=new char[n];
 | 
			
		||||
		for ( i=offset,j=offset+length,n=0; i<j; ) {
 | 
			
		||||
			chars[n++] = (char) (
 | 
			
		||||
				((b=bytes[i++])>=0||i>=j)? b:
 | 
			
		||||
				(b<-32||i+1>=j)? (((b&0x3f) << 6) | (bytes[i++]&0x3f)):
 | 
			
		||||
					(((b&0xf) << 12) | ((bytes[i++]&0x3f)<<6) | (bytes[i++]&0x3f)));
 | 
			
		||||
		}
 | 
			
		||||
		return new String(chars);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Count the number of bytes required to encode the string as UTF-8.
 | 
			
		||||
	 * @param chars Array of unicode characters to be encoded as UTF-8
 | 
			
		||||
	 * @return count of bytes needed to encode using UTF-8
 | 
			
		||||
	 * @see #encodeToUtf8(char[], byte[], int)
 | 
			
		||||
	 * @see #decodeAsUtf8(byte[], int, int)
 | 
			
		||||
	 * @see #isValidUtf8()
 | 
			
		||||
	 */
 | 
			
		||||
	/* DAN200 START */
 | 
			
		||||
	//public static int lengthAsUtf8(char[] chars) {		
 | 
			
		||||
	private static int lengthAsUtf8(char[] chars) {		
 | 
			
		||||
	/* DAN200 END */
 | 
			
		||||
		int i,b;
 | 
			
		||||
		char c;
 | 
			
		||||
		for ( i=b=chars.length; --i>=0; )
 | 
			
		||||
			if ( (c=chars[i]) >=0x80 )
 | 
			
		||||
				b += (c>=0x800)? 2: 1;
 | 
			
		||||
		return b;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Encode the given Java string as UTF-8 bytes, writing the result to bytes
 | 
			
		||||
	 * starting at offset. 
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * The string should be measured first with lengthAsUtf8
 | 
			
		||||
	 * to make sure the given byte array is large enough.
 | 
			
		||||
	 * @param chars Array of unicode characters to be encoded as UTF-8
 | 
			
		||||
	 * @param bytes byte array to hold the result
 | 
			
		||||
	 * @param off offset into the byte array to start writing
 | 
			
		||||
	 * @see #lengthAsUtf8(char[])
 | 
			
		||||
	 * @see #decodeAsUtf8(byte[], int, int)
 | 
			
		||||
	 * @see #isValidUtf8()
 | 
			
		||||
	 */
 | 
			
		||||
	/* DAN200 START */
 | 
			
		||||
	//public static void encodeToUtf8(char[] chars, byte[] bytes, int off) {
 | 
			
		||||
	private static void encodeToUtf8(char[] chars, byte[] bytes, int off) {
 | 
			
		||||
	/* DAN200 END */
 | 
			
		||||
		final int n = chars.length;
 | 
			
		||||
		char c;
 | 
			
		||||
		for ( int i=0, j=off; i<n; i++ ) {
 | 
			
		||||
			if ( (c = chars[i]) < 0x80 ) {
 | 
			
		||||
				bytes[j++] = (byte) c;
 | 
			
		||||
			} else if ( c < 0x800 ) {
 | 
			
		||||
				bytes[j++] = (byte) (0xC0 | ((c>>6)  & 0x1f));
 | 
			
		||||
				bytes[j++] = (byte) (0x80 | ( c      & 0x3f));				
 | 
			
		||||
			} else {
 | 
			
		||||
				bytes[j++] = (byte) (0xE0 | ((c>>12) & 0x0f));
 | 
			
		||||
				bytes[j++] = (byte) (0x80 | ((c>>6)  & 0x3f));
 | 
			
		||||
				bytes[j++] = (byte) (0x80 | ( c      & 0x3f));				
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Check that a byte sequence is valid UTF-8
 | 
			
		||||
	 * @return true if it is valid UTF-8, otherwise false
 | 
			
		||||
	 * @see #lengthAsUtf8(char[])
 | 
			
		||||
	 * @see #encodeToUtf8(char[], byte[], int)
 | 
			
		||||
	 * @see #decodeAsUtf8(byte[], int, int)
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isValidUtf8() {
 | 
			
		||||
		int i,j,n,b,e=0;
 | 
			
		||||
		for ( i=m_offset,j=m_offset+m_length,n=0; i<j; ++n ) {
 | 
			
		||||
			int c = m_bytes[i++];
 | 
			
		||||
			if ( c >= 0 ) continue;
 | 
			
		||||
			if ( ((c & 0xE0) == 0xC0) 
 | 
			
		||||
					&& i<j 
 | 
			
		||||
					&& (m_bytes[i++] & 0xC0) == 0x80) continue;
 | 
			
		||||
			if ( ((c & 0xF0) == 0xE0) 
 | 
			
		||||
					&& i+1<j 
 | 
			
		||||
					&& (m_bytes[i++] & 0xC0) == 0x80 
 | 
			
		||||
					&& (m_bytes[i++] & 0xC0) == 0x80) continue;
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// --------------------- number conversion -----------------------
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * convert to a number using a supplied base, or NIL if it can't be converted
 | 
			
		||||
	 * @param base the base to use, such as 10
 | 
			
		||||
	 * @return IntValue, DoubleValue, or NIL depending on the content of the string.
 | 
			
		||||
	 * @see LuaValue#tonumber() 
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaValue tonumber( int base ) {
 | 
			
		||||
		double d = scannumber( base );
 | 
			
		||||
		return Double.isNaN(d)? NIL: valueOf(d);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Convert to a number in a base, or return Double.NaN if not a number.
 | 
			
		||||
	 * @param base the base to use, such as 10
 | 
			
		||||
	 * @return double value if conversion is valid, or Double.NaN if not 
 | 
			
		||||
	 */
 | 
			
		||||
	public double scannumber( int base ) {
 | 
			
		||||
		if ( base >= 2 && base <= 36 ) {
 | 
			
		||||
			int i=m_offset,j=m_offset+m_length;
 | 
			
		||||
			while ( i<j && m_bytes[i]==' ' ) ++i;
 | 
			
		||||
			while ( i<j && m_bytes[j-1]==' ' ) --j;
 | 
			
		||||
			if ( i>=j )
 | 
			
		||||
				return Double.NaN;
 | 
			
		||||
			if ( ( base == 10 || base == 16 ) && ( m_bytes[i]=='0' && i+1<j && (m_bytes[i+1]=='x'||m_bytes[i+1]=='X') ) ) {
 | 
			
		||||
				base = 16;
 | 
			
		||||
				i+=2;
 | 
			
		||||
			}
 | 
			
		||||
			double l = scanlong( base, i, j );
 | 
			
		||||
			return Double.isNaN(l) && base==10? scandouble(i,j): l;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		return Double.NaN;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Scan and convert a long value, or return Double.NaN if not found.
 | 
			
		||||
	 * @param base the base to use, such as 10
 | 
			
		||||
	 * @param start the index to start searching from
 | 
			
		||||
	 * @param end the first index beyond the search range
 | 
			
		||||
	 * @return double value if conversion is valid, 
 | 
			
		||||
	 * or Double.NaN if not
 | 
			
		||||
	 */
 | 
			
		||||
	private double scanlong( int base, int start, int end ) {
 | 
			
		||||
		long x = 0;
 | 
			
		||||
		boolean neg = (m_bytes[start] == '-');
 | 
			
		||||
		for ( int i=(neg?start+1:start); i<end; i++ ) {
 | 
			
		||||
			int digit = m_bytes[i] - (base<=10||(m_bytes[i]>='0'&&m_bytes[i]<='9')? '0':
 | 
			
		||||
					m_bytes[i]>='A'&&m_bytes[i]<='Z'? ('A'-10): ('a'-10));
 | 
			
		||||
			if ( digit < 0 || digit >= base )
 | 
			
		||||
				return Double.NaN;		
 | 
			
		||||
			x = x * base + digit;
 | 
			
		||||
		}
 | 
			
		||||
		return neg? -x: x;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Scan and convert a double value, or return Double.NaN if not a double.
 | 
			
		||||
	 * @param start the index to start searching from
 | 
			
		||||
	 * @param end the first index beyond the search range
 | 
			
		||||
	 * @return double value if conversion is valid, 
 | 
			
		||||
	 * or Double.NaN if not
 | 
			
		||||
	 */
 | 
			
		||||
	private double scandouble(int start, int end) {
 | 
			
		||||
		if ( end>start+64 ) end=start+64;
 | 
			
		||||
		for ( int i=start; i<end; i++ ) {
 | 
			
		||||
			switch ( m_bytes[i] ) {
 | 
			
		||||
			case '-':
 | 
			
		||||
			case '+':
 | 
			
		||||
			case '.':
 | 
			
		||||
			case 'e': case 'E':
 | 
			
		||||
			case '0': case '1': case '2': case '3': case '4':
 | 
			
		||||
			case '5': case '6': case '7': case '8': case '9':
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				return Double.NaN;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		char [] c = new char[end-start];
 | 
			
		||||
		for ( int i=start; i<end; i++ )
 | 
			
		||||
			c[i-start] = (char) m_bytes[i];
 | 
			
		||||
		try {
 | 
			
		||||
			return Double.parseDouble(new String(c));
 | 
			
		||||
		} catch ( Exception e ) {			
 | 
			
		||||
			return Double.NaN;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,718 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
import java.util.Vector;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Subclass of {@link LuaValue} for representing lua tables. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Almost all API's implemented in {@link LuaTable} are defined and documented in {@link LuaValue}.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * If a table is needed, the one of the type-checking functions can be used such as
 | 
			
		||||
 * {@link #istable()}, 
 | 
			
		||||
 * {@link #checktable()}, or
 | 
			
		||||
 * {@link #opttable(LuaTable)} 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The main table operations are defined on {@link LuaValue} 
 | 
			
		||||
 * for getting and setting values with and without metatag processing:
 | 
			
		||||
 * <ul>
 | 
			
		||||
 * <li>{@link #get(LuaValue)}</li>  
 | 
			
		||||
 * <li>{@link #set(LuaValue,LuaValue)}</li>  
 | 
			
		||||
 * <li>{@link #rawget(LuaValue)}</li>  
 | 
			
		||||
 * <li>{@link #rawset(LuaValue,LuaValue)}</li>
 | 
			
		||||
 * <li>plus overloads such as {@link #get(String)}, {@link #get(int)}, and so on</li>  
 | 
			
		||||
 * </ul>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To iterate over key-value pairs from Java, use
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LuaValue k = LuaValue.NIL;
 | 
			
		||||
 * while ( true ) {
 | 
			
		||||
 *    Varargs n = table.next(k);
 | 
			
		||||
 *    if ( (k = n.arg1()).isnil() )
 | 
			
		||||
 *       break;
 | 
			
		||||
 *    LuaValue v = n.arg(2)
 | 
			
		||||
 *    process( k, v )
 | 
			
		||||
 * }}</pre>
 | 
			
		||||
 * 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * As with other types, {@link LuaTable} instances should be constructed via one of the table constructor 
 | 
			
		||||
 * methods on {@link LuaValue}:
 | 
			
		||||
 * <ul>
 | 
			
		||||
 * <li>{@link LuaValue#tableOf()} empty table</li>
 | 
			
		||||
 * <li>{@link LuaValue#tableOf(int, int)} table with capacity</li>
 | 
			
		||||
 * <li>{@link LuaValue#listOf(LuaValue[])} initialize array part</li>
 | 
			
		||||
 * <li>{@link LuaValue#listOf(LuaValue[], Varargs)} initialize array part</li>
 | 
			
		||||
 * <li>{@link LuaValue#tableOf(LuaValue[])} initialize named hash part</li>
 | 
			
		||||
 * <li>{@link LuaValue#tableOf(Varargs, int)} initialize named hash part</li>
 | 
			
		||||
 * <li>{@link LuaValue#tableOf(LuaValue[], LuaValue[])} initialize array and named parts</li>
 | 
			
		||||
 * <li>{@link LuaValue#tableOf(LuaValue[], LuaValue[], Varargs)} initialize array and named parts</li>
 | 
			
		||||
 * </ul>
 | 
			
		||||
 * @see LuaValue
 | 
			
		||||
 */
 | 
			
		||||
public class LuaTable extends LuaValue {
 | 
			
		||||
	private static final int      MIN_HASH_CAPACITY = 2;
 | 
			
		||||
	private static final LuaString N = valueOf("n");
 | 
			
		||||
	
 | 
			
		||||
	/** the array values */
 | 
			
		||||
	protected LuaValue[] array;
 | 
			
		||||
	
 | 
			
		||||
	/** the hash keys */
 | 
			
		||||
	protected LuaValue[] hashKeys;
 | 
			
		||||
	
 | 
			
		||||
	/** the hash values */
 | 
			
		||||
	protected LuaValue[] hashValues;
 | 
			
		||||
	
 | 
			
		||||
	/** the number of hash entries */
 | 
			
		||||
	protected int hashEntries;
 | 
			
		||||
	
 | 
			
		||||
	/** metatable for this table, or null */
 | 
			
		||||
	protected LuaValue m_metatable;
 | 
			
		||||
	
 | 
			
		||||
	/** Construct empty table */
 | 
			
		||||
	public LuaTable() {
 | 
			
		||||
		array = NOVALS;
 | 
			
		||||
		hashKeys = NOVALS;
 | 
			
		||||
		hashValues = NOVALS;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Construct table with preset capacity.
 | 
			
		||||
	 * @param narray capacity of array part
 | 
			
		||||
	 * @param nhash capacity of hash part
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaTable(int narray, int nhash) {
 | 
			
		||||
		presize(narray, nhash);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Construct table with named and unnamed parts. 
 | 
			
		||||
	 * @param named Named elements in order {@code key-a, value-a, key-b, value-b, ... }
 | 
			
		||||
	 * @param unnamed Unnamed elements in order {@code value-1, value-2, ... } 
 | 
			
		||||
	 * @param lastarg Additional unnamed values beyond {@code unnamed.length}
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaTable(LuaValue[] named, LuaValue[] unnamed, Varargs lastarg) {
 | 
			
		||||
		int nn = (named!=null? named.length: 0);
 | 
			
		||||
		int nu = (unnamed!=null? unnamed.length: 0);
 | 
			
		||||
		int nl = (lastarg!=null? lastarg.narg(): 0);
 | 
			
		||||
		presize(nu+nl, nn-(nn>>1));
 | 
			
		||||
		for ( int i=0; i<nu; i++ )
 | 
			
		||||
			rawset(i+1,unnamed[i]);
 | 
			
		||||
		if ( lastarg != null )
 | 
			
		||||
			for ( int i=1,n=lastarg.narg(); i<=n; ++i )
 | 
			
		||||
				rawset(nu+i,lastarg.arg(i));
 | 
			
		||||
		for ( int i=0; i<nn; i+=2 )
 | 
			
		||||
			if (!named[i+1].isnil())
 | 
			
		||||
				rawset(named[i], named[i+1]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Construct table of unnamed elements. 
 | 
			
		||||
	 * @param varargs Unnamed elements in order {@code value-1, value-2, ... } 
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaTable(Varargs varargs) {
 | 
			
		||||
		this(varargs,1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Construct table of unnamed elements. 
 | 
			
		||||
	 * @param varargs Unnamed elements in order {@code value-1, value-2, ... }
 | 
			
		||||
	 * @param firstarg the index in varargs of the first argument to include in the table 
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaTable(Varargs varargs, int firstarg) {
 | 
			
		||||
		int nskip = firstarg-1;
 | 
			
		||||
		int n = Math.max(varargs.narg()-nskip,0);
 | 
			
		||||
		presize( n, 1 );
 | 
			
		||||
		set(N, valueOf(n));
 | 
			
		||||
		for ( int i=1; i<=n; i++ )
 | 
			
		||||
			set(i, varargs.arg(i+nskip));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int type() {
 | 
			
		||||
		return LuaValue.TTABLE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String typename() {
 | 
			
		||||
		return "table";
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean istable() { 
 | 
			
		||||
		return true; 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaTable checktable()     { 
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaTable opttable(LuaTable defval)  {
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void presize( int narray ) {
 | 
			
		||||
		if ( narray > array.length )
 | 
			
		||||
			array = resize( array, narray );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void presize(int narray, int nhash) {
 | 
			
		||||
		if ( nhash > 0 && nhash < MIN_HASH_CAPACITY )
 | 
			
		||||
			nhash = MIN_HASH_CAPACITY;
 | 
			
		||||
		array = (narray>0? new LuaValue[narray]: NOVALS);
 | 
			
		||||
		hashKeys = (nhash>0? new LuaValue[nhash]: NOVALS);
 | 
			
		||||
		hashValues = (nhash>0? new LuaValue[nhash]: NOVALS);
 | 
			
		||||
		hashEntries = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Resize the table */
 | 
			
		||||
	private static LuaValue[] resize( LuaValue[] old, int n ) {
 | 
			
		||||
		LuaValue[] v = new LuaValue[n];
 | 
			
		||||
		System.arraycopy(old, 0, v, 0, old.length);
 | 
			
		||||
		return v;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Get the length of the array part of the table. 
 | 
			
		||||
	 * @return length of the array part, does not relate to count of objects in the table. 
 | 
			
		||||
	 */
 | 
			
		||||
	protected int getArrayLength() {
 | 
			
		||||
		return array.length;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Get the length of the hash part of the table. 
 | 
			
		||||
	 * @return length of the hash part, does not relate to count of objects in the table. 
 | 
			
		||||
	 */
 | 
			
		||||
	protected int getHashLength() {
 | 
			
		||||
		return hashValues.length;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue getmetatable() {
 | 
			
		||||
		return m_metatable;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue setmetatable(LuaValue metatable) {
 | 
			
		||||
		m_metatable = metatable;
 | 
			
		||||
		LuaValue mode;
 | 
			
		||||
		if ( m_metatable!=null && (mode=m_metatable.rawget(MODE)).isstring() ) {
 | 
			
		||||
			String m = mode.tojstring();
 | 
			
		||||
			boolean k = m.indexOf('k')>=0;
 | 
			
		||||
			boolean v = m.indexOf('v')>=0;
 | 
			
		||||
			return changemode(k,v);
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Change the mode of a table
 | 
			
		||||
	 * @param weakkeys true to make the table have weak keys going forward
 | 
			
		||||
	 * @param weakvalues true to make the table have weak values going forward
 | 
			
		||||
	 * @return {@code this} or a new {@link WeakTable} if the mode change requires copying.
 | 
			
		||||
	 */
 | 
			
		||||
	protected LuaTable changemode(boolean weakkeys, boolean weakvalues) {
 | 
			
		||||
		if ( weakkeys || weakvalues )
 | 
			
		||||
			return new WeakTable(weakkeys, weakvalues, this);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue get( int key ) {
 | 
			
		||||
		LuaValue v = rawget(key);
 | 
			
		||||
		return v.isnil() && m_metatable!=null? gettable(this,valueOf(key)): v;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue get( LuaValue key ) {
 | 
			
		||||
		LuaValue v = rawget(key);
 | 
			
		||||
		return v.isnil() && m_metatable!=null? gettable(this,key): v;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue rawget( int key ) {
 | 
			
		||||
		if ( key>0 && key<=array.length ) 
 | 
			
		||||
			return array[key-1]!=null? array[key-1]: NIL;
 | 
			
		||||
		return hashget( LuaInteger.valueOf(key) );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue rawget( LuaValue key ) {
 | 
			
		||||
		if ( key.isinttype() ) {
 | 
			
		||||
			int ikey = key.toint();
 | 
			
		||||
			if ( ikey>0 && ikey<=array.length ) 
 | 
			
		||||
				return array[ikey-1]!=null? array[ikey-1]: NIL;
 | 
			
		||||
		}
 | 
			
		||||
		return hashget( key );
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
	protected LuaValue hashget(LuaValue key) {
 | 
			
		||||
		if ( hashEntries > 0 ) {
 | 
			
		||||
			LuaValue v = hashValues[hashFindSlot(key)];
 | 
			
		||||
			return v!=null? v: NIL;
 | 
			
		||||
		}
 | 
			
		||||
		return NIL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void set( int key, LuaValue value ) {
 | 
			
		||||
		if ( m_metatable==null || ! rawget(key).isnil() || ! settable(this,LuaInteger.valueOf(key),value) )
 | 
			
		||||
			rawset(key, value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** caller must ensure key is not nil */
 | 
			
		||||
	public void set( LuaValue key, LuaValue value ) {
 | 
			
		||||
		key.checkvalidkey();
 | 
			
		||||
		if ( m_metatable==null || ! rawget(key).isnil() ||  ! settable(this,key,value) )
 | 
			
		||||
			rawset(key, value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void rawset( int key, LuaValue value ) {
 | 
			
		||||
		if ( ! arrayset(key, value) )
 | 
			
		||||
			hashset( LuaInteger.valueOf(key), value );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** caller must ensure key is not nil */
 | 
			
		||||
	public void rawset( LuaValue key, LuaValue value ) {
 | 
			
		||||
		if ( !key.isinttype() || !arrayset(key.toint(), value) )
 | 
			
		||||
			hashset( key, value );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Set an array element */
 | 
			
		||||
	private boolean arrayset( int key, LuaValue value ) {
 | 
			
		||||
		if ( key>0 && key<=array.length ) {
 | 
			
		||||
			array[key-1] = (value.isnil()? null: value);
 | 
			
		||||
			return true;
 | 
			
		||||
		} else if ( key==array.length+1 && !value.isnil() ) {
 | 
			
		||||
			expandarray();
 | 
			
		||||
			array[key-1] = value;
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Expand the array part */
 | 
			
		||||
	private void expandarray() {
 | 
			
		||||
		int n = array.length;
 | 
			
		||||
		int m = Math.max(2,n*2);
 | 
			
		||||
		array = resize(array, m);
 | 
			
		||||
		for ( int i=n; i<m; i++ ) {
 | 
			
		||||
			LuaValue k = LuaInteger.valueOf(i+1);
 | 
			
		||||
			LuaValue v = hashget(k);
 | 
			
		||||
			if ( !v.isnil() ) {
 | 
			
		||||
				hashset(k, NIL);
 | 
			
		||||
				array[i] = v;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Remove the element at a position in a list-table
 | 
			
		||||
	 *  
 | 
			
		||||
	 * @param pos the position to remove
 | 
			
		||||
	 * @return The removed item, or {@link #NONE} if not removed
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaValue remove(int pos) {
 | 
			
		||||
		int n = length();
 | 
			
		||||
		if ( pos == 0 )
 | 
			
		||||
			pos = n;
 | 
			
		||||
		else if (pos > n)
 | 
			
		||||
			return NONE;
 | 
			
		||||
		LuaValue v = rawget(pos);
 | 
			
		||||
		for ( LuaValue r=v; !r.isnil(); ) {
 | 
			
		||||
			r = rawget(pos+1);
 | 
			
		||||
			rawset(pos++, r);
 | 
			
		||||
		}
 | 
			
		||||
		return v.isnil()? NONE: v;
 | 
			
		||||
	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Insert an element at a position in a list-table
 | 
			
		||||
	 *  
 | 
			
		||||
	 * @param pos the position to remove
 | 
			
		||||
	 * @param value The value to insert
 | 
			
		||||
	 */
 | 
			
		||||
	public void insert(int pos, LuaValue value) {
 | 
			
		||||
		if ( pos == 0 )
 | 
			
		||||
			pos = length()+1;
 | 
			
		||||
		while ( ! value.isnil() ) {
 | 
			
		||||
			LuaValue v = rawget( pos );
 | 
			
		||||
			rawset(pos++, value);
 | 
			
		||||
			value = v;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Concatenate the contents of a table efficiently, using {@link Buffer}
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param sep {@link LuaString} separater to apply between elements
 | 
			
		||||
	 * @param i the first element index
 | 
			
		||||
	 * @param j the last element index, inclusive
 | 
			
		||||
	 * @return {@link LuaString} value of the concatenation
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaValue concat(LuaString sep, int i, int j) {
 | 
			
		||||
		Buffer  sb = new Buffer ();
 | 
			
		||||
		if ( i<=j ) {
 | 
			
		||||
			sb.append( get(i).checkstring() );
 | 
			
		||||
			while ( ++i<=j ) {
 | 
			
		||||
				sb.append( sep );
 | 
			
		||||
				sb.append( get(i).checkstring() );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return sb.tostring();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue getn() { 
 | 
			
		||||
		for ( int n=getArrayLength(); n>0; --n )
 | 
			
		||||
			if ( !rawget(n).isnil() )
 | 
			
		||||
				return LuaInteger.valueOf(n);
 | 
			
		||||
		return ZERO;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int length() {
 | 
			
		||||
		int a = getArrayLength();
 | 
			
		||||
		int n = a+1,m=0;
 | 
			
		||||
		while ( !rawget(n).isnil() ) {
 | 
			
		||||
			m = n;
 | 
			
		||||
			n += a+getHashLength()+1;
 | 
			
		||||
		}
 | 
			
		||||
		while ( n > m+1 ) {
 | 
			
		||||
			int k = (n+m) / 2;
 | 
			
		||||
			if ( !rawget(k).isnil() )
 | 
			
		||||
				m = k;
 | 
			
		||||
			else
 | 
			
		||||
				n = k;
 | 
			
		||||
		}
 | 
			
		||||
		return m;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue len()  { 
 | 
			
		||||
		return LuaInteger.valueOf(length());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Return table.maxn() as defined by lua 5.0.
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Provided for compatibility, not a scalable operation. 
 | 
			
		||||
	 * @return value for maxn
 | 
			
		||||
	 */
 | 
			
		||||
	public int maxn() {
 | 
			
		||||
		int n = 0;
 | 
			
		||||
		for ( int i=0; i<array.length; i++ )
 | 
			
		||||
			if ( array[i] != null )
 | 
			
		||||
				n = i+1;
 | 
			
		||||
		for ( int i=0; i<hashKeys.length; i++ ) {
 | 
			
		||||
			LuaValue v = hashKeys[i];
 | 
			
		||||
			if ( v!=null && v.isinttype() ) {
 | 
			
		||||
				int key = v.toint();
 | 
			
		||||
				if ( key > n )
 | 
			
		||||
					n = key;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return n;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the next element after a particular key in the table 
 | 
			
		||||
	 * @return key,value or nil
 | 
			
		||||
	 */
 | 
			
		||||
	public Varargs next( LuaValue key ) {
 | 
			
		||||
		int i = 0;
 | 
			
		||||
		do {
 | 
			
		||||
			// find current key index
 | 
			
		||||
			if ( ! key.isnil() ) {
 | 
			
		||||
				if ( key.isinttype() ) { 
 | 
			
		||||
					i = key.toint();
 | 
			
		||||
					if ( i>0 && i<=array.length ) {
 | 
			
		||||
						if ( array[i-1] == null )
 | 
			
		||||
							error( "invalid key to 'next'" );
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if ( hashKeys.length == 0 )
 | 
			
		||||
					error( "invalid key to 'next'" );
 | 
			
		||||
				i = hashFindSlot(key);
 | 
			
		||||
				if ( hashKeys[i] == null )
 | 
			
		||||
					error( "invalid key to 'next'" );
 | 
			
		||||
				i += 1+array.length;
 | 
			
		||||
			}
 | 
			
		||||
		} while ( false );
 | 
			
		||||
		
 | 
			
		||||
		// check array part
 | 
			
		||||
		for ( ; i<array.length; ++i )
 | 
			
		||||
			if ( array[i] != null )
 | 
			
		||||
				return varargsOf(LuaInteger.valueOf(i+1),array[i]);
 | 
			
		||||
 | 
			
		||||
		// check hash part
 | 
			
		||||
		for ( i-=array.length; i<hashKeys.length; ++i )
 | 
			
		||||
			if ( hashKeys[i] != null )
 | 
			
		||||
				return varargsOf(hashKeys[i],hashValues[i]);
 | 
			
		||||
		
 | 
			
		||||
		// nothing found, push nil, return nil.
 | 
			
		||||
		return NIL;
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the next element after a particular key in the 
 | 
			
		||||
	 * contiguous array part of a table 
 | 
			
		||||
	 * @return key,value or none
 | 
			
		||||
	 */
 | 
			
		||||
	public Varargs inext(LuaValue key) {
 | 
			
		||||
		int k = key.checkint() + 1;
 | 
			
		||||
		LuaValue v = rawget(k);
 | 
			
		||||
		return v.isnil()? NONE: varargsOf(LuaInteger.valueOf(k),v);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Call the supplied function once for each key-value pair
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param func function to call
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaValue foreach(LuaValue func) {
 | 
			
		||||
		Varargs n;
 | 
			
		||||
		LuaValue k = NIL;
 | 
			
		||||
		LuaValue v;
 | 
			
		||||
		while ( !(k = ((n = next(k)).arg1())).isnil() )
 | 
			
		||||
			if ( ! (v = func.call(k, n.arg(2))).isnil() )
 | 
			
		||||
				return v;
 | 
			
		||||
		return NIL;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Call the supplied function once for each key-value pair 
 | 
			
		||||
	 * in the contiguous array part
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param func
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaValue foreachi(LuaValue func) {
 | 
			
		||||
		LuaValue v,r;
 | 
			
		||||
		for ( int k=0; !(v = rawget(++k)).isnil(); )
 | 
			
		||||
			if ( ! (r = func.call(valueOf(k), v)).isnil() )
 | 
			
		||||
				return r;
 | 
			
		||||
		return NIL;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set a hashtable value
 | 
			
		||||
	 * @param key key to set
 | 
			
		||||
	 * @param value value to set
 | 
			
		||||
	 */
 | 
			
		||||
	public void hashset(LuaValue key, LuaValue value) {
 | 
			
		||||
		if ( value.isnil() )
 | 
			
		||||
			hashRemove(key);
 | 
			
		||||
		else {
 | 
			
		||||
			if ( hashKeys.length == 0 ) {
 | 
			
		||||
				hashKeys = new LuaValue[ MIN_HASH_CAPACITY ];
 | 
			
		||||
				hashValues = new LuaValue[ MIN_HASH_CAPACITY ];
 | 
			
		||||
			}
 | 
			
		||||
			int slot = hashFindSlot( key );
 | 
			
		||||
			if ( hashFillSlot( slot, value ) )
 | 
			
		||||
				return;
 | 
			
		||||
			hashKeys[slot] = key;
 | 
			
		||||
			hashValues[slot] = value;
 | 
			
		||||
			if ( checkLoadFactor() )
 | 
			
		||||
				rehash();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Find the hashtable slot to use
 | 
			
		||||
	 * @param key key to look for
 | 
			
		||||
	 * @return slot to use
 | 
			
		||||
	 */
 | 
			
		||||
	public int hashFindSlot(LuaValue key) {		
 | 
			
		||||
		int i = ( key.hashCode() & 0x7FFFFFFF ) % hashKeys.length;
 | 
			
		||||
		
 | 
			
		||||
		// This loop is guaranteed to terminate as long as we never allow the
 | 
			
		||||
		// table to get 100% full.
 | 
			
		||||
		LuaValue k;
 | 
			
		||||
		while ( ( k = hashKeys[i] ) != null && !k.raweq(key) ) {
 | 
			
		||||
			i = ( i + 1 ) % hashKeys.length;
 | 
			
		||||
		}
 | 
			
		||||
		return i;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private boolean hashFillSlot( int slot, LuaValue value ) {
 | 
			
		||||
		hashValues[ slot ] = value;
 | 
			
		||||
		if ( hashKeys[ slot ] != null ) {
 | 
			
		||||
			return true;
 | 
			
		||||
		} else {
 | 
			
		||||
			++hashEntries;
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void hashRemove( LuaValue key ) {
 | 
			
		||||
		if ( hashKeys.length > 0 ) {
 | 
			
		||||
			int slot = hashFindSlot( key );
 | 
			
		||||
			hashClearSlot( slot );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Clear a particular slot in the table
 | 
			
		||||
	 * @param i slot to clear.
 | 
			
		||||
	 */
 | 
			
		||||
	protected void hashClearSlot( int i ) {
 | 
			
		||||
		if ( hashKeys[ i ] != null ) {
 | 
			
		||||
			
 | 
			
		||||
			int j = i;
 | 
			
		||||
			int n = hashKeys.length; 
 | 
			
		||||
			while ( hashKeys[ j = ( ( j + 1 ) % n ) ] != null ) {
 | 
			
		||||
				final int k = ( ( hashKeys[ j ].hashCode() )& 0x7FFFFFFF ) % n;
 | 
			
		||||
				if ( ( j > i && ( k <= i || k > j ) ) ||
 | 
			
		||||
					 ( j < i && ( k <= i && k > j ) ) ) {
 | 
			
		||||
					hashKeys[ i ] = hashKeys[ j ];
 | 
			
		||||
					hashValues[ i ] = hashValues[ j ];
 | 
			
		||||
					i = j;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			--hashEntries;
 | 
			
		||||
			hashKeys[ i ] = null;
 | 
			
		||||
			hashValues[ i ] = null;
 | 
			
		||||
			
 | 
			
		||||
			if ( hashEntries == 0 ) {
 | 
			
		||||
				hashKeys = NOVALS;
 | 
			
		||||
				hashValues = NOVALS;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private boolean checkLoadFactor() {
 | 
			
		||||
		// Using a load factor of (n+1) >= 7/8 because that is easy to compute without
 | 
			
		||||
		// overflow or division.
 | 
			
		||||
		final int hashCapacity = hashKeys.length;
 | 
			
		||||
		return hashEntries >= (hashCapacity - (hashCapacity>>3));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void rehash() {
 | 
			
		||||
		final int oldCapacity = hashKeys.length;
 | 
			
		||||
		final int newCapacity = oldCapacity+(oldCapacity>>2)+MIN_HASH_CAPACITY;
 | 
			
		||||
		
 | 
			
		||||
		final LuaValue[] oldKeys = hashKeys;
 | 
			
		||||
		final LuaValue[] oldValues = hashValues;
 | 
			
		||||
		
 | 
			
		||||
		hashKeys = new LuaValue[ newCapacity ];
 | 
			
		||||
		hashValues = new LuaValue[ newCapacity ];
 | 
			
		||||
		
 | 
			
		||||
		for ( int i = 0; i < oldCapacity; ++i ) {
 | 
			
		||||
			final LuaValue k = oldKeys[i];
 | 
			
		||||
			if ( k != null ) {
 | 
			
		||||
				final LuaValue v = oldValues[i];
 | 
			
		||||
				final int slot = hashFindSlot( k );
 | 
			
		||||
				hashKeys[slot] = k;
 | 
			
		||||
				hashValues[slot] = v;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// ----------------- sort support -----------------------------
 | 
			
		||||
	//
 | 
			
		||||
	// implemented heap sort from wikipedia
 | 
			
		||||
	//
 | 
			
		||||
	// Only sorts the contiguous array part. 
 | 
			
		||||
	//
 | 
			
		||||
	/** Sort the table using a comparator.
 | 
			
		||||
	 * @param comparator {@link LuaValue} to be called to compare elements.
 | 
			
		||||
	 */
 | 
			
		||||
	public void sort(LuaValue comparator) {
 | 
			
		||||
		int n = array.length;
 | 
			
		||||
		while ( n > 0 && array[n-1] == null )
 | 
			
		||||
			--n;
 | 
			
		||||
		if ( n > 1 ) 
 | 
			
		||||
			heapSort(n, comparator);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void heapSort(int count, LuaValue cmpfunc) {
 | 
			
		||||
		heapify(count, cmpfunc);
 | 
			
		||||
		for ( int end=count-1; end>0; ) {
 | 
			
		||||
			swap(end, 0);
 | 
			
		||||
			siftDown(0, --end, cmpfunc);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void heapify(int count, LuaValue cmpfunc) {
 | 
			
		||||
		for ( int start=count/2-1; start>=0; --start )
 | 
			
		||||
			siftDown(start, count - 1, cmpfunc);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void siftDown(int start, int end, LuaValue cmpfunc) {
 | 
			
		||||
		for ( int root=start; root*2+1 <= end; ) { 
 | 
			
		||||
			int child = root*2+1; 
 | 
			
		||||
			if (child < end && compare(child, child + 1, cmpfunc))
 | 
			
		||||
				++child; 
 | 
			
		||||
			if (compare(root, child, cmpfunc)) {
 | 
			
		||||
				swap(root, child);
 | 
			
		||||
				root = child;
 | 
			
		||||
			} else
 | 
			
		||||
				return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private boolean compare(int i, int j, LuaValue cmpfunc) {
 | 
			
		||||
		LuaValue a = array[i];
 | 
			
		||||
		LuaValue b = array[j];
 | 
			
		||||
		if ( a == null || b == null )
 | 
			
		||||
			return false;
 | 
			
		||||
		if ( ! cmpfunc.isnil() ) {
 | 
			
		||||
			return cmpfunc.call(a,b).toboolean();
 | 
			
		||||
		} else {
 | 
			
		||||
			return a.lt_b(b);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void swap(int i, int j) {
 | 
			
		||||
		LuaValue a = array[i];
 | 
			
		||||
		array[i] = array[j];
 | 
			
		||||
		array[j] = a;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** This may be deprecated in a future release.  
 | 
			
		||||
	 * It is recommended to count via iteration over next() instead
 | 
			
		||||
	 * @return count of keys in the table 
 | 
			
		||||
	 * */
 | 
			
		||||
	public int keyCount() {
 | 
			
		||||
		LuaValue k = LuaValue.NIL;
 | 
			
		||||
		for ( int i=0; true; i++ ) {
 | 
			
		||||
			Varargs n = next(k);
 | 
			
		||||
			if ( (k = n.arg1()).isnil() )
 | 
			
		||||
				return i;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** This may be deprecated in a future release.  
 | 
			
		||||
	 * It is recommended to use next() instead 
 | 
			
		||||
	 * @return array of keys in the table 
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaValue[] keys() {
 | 
			
		||||
		Vector l = new Vector();
 | 
			
		||||
		LuaValue k = LuaValue.NIL;
 | 
			
		||||
		while ( true ) {
 | 
			
		||||
			Varargs n = next(k);
 | 
			
		||||
			if ( (k = n.arg1()).isnil() )
 | 
			
		||||
				break;
 | 
			
		||||
			l.addElement( k );
 | 
			
		||||
		}
 | 
			
		||||
		LuaValue[] a = new LuaValue[l.size()];
 | 
			
		||||
		l.copyInto(a);
 | 
			
		||||
		return a;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// equality w/ metatable processing
 | 
			
		||||
	public LuaValue eq( LuaValue val ) {  return eq_b(val)? TRUE: FALSE; }
 | 
			
		||||
	public boolean eq_b( LuaValue val )  {
 | 
			
		||||
		if ( this == val ) return true;
 | 
			
		||||
		if ( m_metatable == null || !val.istable() ) return false;
 | 
			
		||||
		LuaValue valmt = val.getmetatable();
 | 
			
		||||
		return valmt!=null && LuaValue.eqmtcall(this, m_metatable, val, valmt); 
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,433 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2007-2012 LuaJ. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* DAN200 START */
 | 
			
		||||
import java.lang.ref.WeakReference;
 | 
			
		||||
import java.util.Enumeration;
 | 
			
		||||
import java.util.Vector;
 | 
			
		||||
/* DAN200 END */
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.lib.DebugLib;
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Subclass of {@link LuaValue} that implements 
 | 
			
		||||
 * a lua coroutine thread using Java Threads.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * A LuaThread is typically created in response to a scripted call to 
 | 
			
		||||
 * {@code coroutine.create()}
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The threads must be initialized with the globals, so that 
 | 
			
		||||
 * the global environment may be passed along according to rules of lua. 
 | 
			
		||||
 * This is done via a call to {@link #setGlobals(LuaValue)} 
 | 
			
		||||
 * at some point during globals initialization.
 | 
			
		||||
 * See {@link BaseLib} for additional documentation and example code.  
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * The utility classes {@link JsePlatform} and {@link JmePlatform} 
 | 
			
		||||
 * see to it that this initialization is done properly.  
 | 
			
		||||
 * For this reason it is highly recommended to use one of these classes
 | 
			
		||||
 * when initializing globals. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The behavior of coroutine threads matches closely the behavior 
 | 
			
		||||
 * of C coroutine library.  However, because of the use of Java threads 
 | 
			
		||||
 * to manage call state, it is possible to yield from anywhere in luaj. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Each Java thread wakes up at regular intervals and checks a weak reference
 | 
			
		||||
 * to determine if it can ever be resumed.  If not, it throws 
 | 
			
		||||
 * {@link OrphanedThread} which is an {@link java.lang.Error}. 
 | 
			
		||||
 * Applications should not catch {@link OrphanedThread}, because it can break
 | 
			
		||||
 * the thread safety of luaj.
 | 
			
		||||
 *   
 | 
			
		||||
 * @see LuaValue
 | 
			
		||||
 * @see JsePlatform
 | 
			
		||||
 * @see JmePlatform
 | 
			
		||||
 * @see CoroutineLib
 | 
			
		||||
 */
 | 
			
		||||
public class LuaThread extends LuaValue {
 | 
			
		||||
	
 | 
			
		||||
	public static LuaValue s_metatable;
 | 
			
		||||
 | 
			
		||||
	public static int coroutine_count = 0;
 | 
			
		||||
 | 
			
		||||
	/** Interval at which to check for lua threads that are no longer referenced. 
 | 
			
		||||
	 * This can be changed by Java startup code if desired.
 | 
			
		||||
	 */
 | 
			
		||||
	static long thread_orphan_check_interval = 30000;
 | 
			
		||||
	
 | 
			
		||||
	private static final int STATUS_INITIAL       = 0;
 | 
			
		||||
	private static final int STATUS_SUSPENDED     = 1;
 | 
			
		||||
	private static final int STATUS_RUNNING       = 2;
 | 
			
		||||
	private static final int STATUS_NORMAL        = 3;
 | 
			
		||||
	private static final int STATUS_DEAD          = 4;
 | 
			
		||||
	private static final String[] STATUS_NAMES = { 
 | 
			
		||||
		"suspended", 
 | 
			
		||||
		"suspended", 
 | 
			
		||||
		"running", 
 | 
			
		||||
		"normal", 
 | 
			
		||||
		"dead",};
 | 
			
		||||
	
 | 
			
		||||
	private LuaValue env;
 | 
			
		||||
	private final State state;
 | 
			
		||||
 | 
			
		||||
	/** Field to hold state of error condition during debug hook function calls. */
 | 
			
		||||
	public LuaValue err;
 | 
			
		||||
	
 | 
			
		||||
	final CallStack callstack = new CallStack();
 | 
			
		||||
	
 | 
			
		||||
	public static final int        MAX_CALLSTACK = 256;
 | 
			
		||||
	
 | 
			
		||||
	private static final LuaThread main_thread = new LuaThread();
 | 
			
		||||
	
 | 
			
		||||
	// state of running thread including call stack
 | 
			
		||||
	private static LuaThread       running_thread    = main_thread;
 | 
			
		||||
 | 
			
		||||
	/** Interval to check for LuaThread dereferencing.  */
 | 
			
		||||
	public static int GC_INTERVAL = 30000;
 | 
			
		||||
 | 
			
		||||
	/** Thread-local used by DebugLib to store debugging state.  */
 | 
			
		||||
	public Object debugState;
 | 
			
		||||
 | 
			
		||||
	/* DAN200 START */
 | 
			
		||||
    private Vector children = new Vector();
 | 
			
		||||
    /* DAN200 END */
 | 
			
		||||
 | 
			
		||||
	/** Private constructor for main thread only */
 | 
			
		||||
	private LuaThread() {
 | 
			
		||||
		state = new State(this, null);
 | 
			
		||||
		state.status = STATUS_RUNNING;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Create a LuaThread around a function and environment
 | 
			
		||||
	 * @param func The function to execute
 | 
			
		||||
	 * @param env The environment to apply to the thread
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaThread(LuaValue func, LuaValue env) {	
 | 
			
		||||
		LuaValue.assert_(func != null, "function cannot be null");
 | 
			
		||||
		this.env = env;
 | 
			
		||||
		state = new State(this, func);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int type() {
 | 
			
		||||
		return LuaValue.TTHREAD;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public String typename() {
 | 
			
		||||
		return "thread";
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isthread() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaThread optthread(LuaThread defval) {
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaThread checkthread() {
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue getmetatable() { 
 | 
			
		||||
		return s_metatable; 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue getfenv() {
 | 
			
		||||
		return env;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void setfenv(LuaValue env) {
 | 
			
		||||
		this.env = env;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String getStatus() {
 | 
			
		||||
		return STATUS_NAMES[state.status];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the currently running thread. 
 | 
			
		||||
	 * @return {@link LuaThread} that is currenly running
 | 
			
		||||
	 */
 | 
			
		||||
	public static LuaThread getRunning() {
 | 
			
		||||
		return running_thread;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Test if this is the main thread 
 | 
			
		||||
	 * @return true if this is the main thread
 | 
			
		||||
	 */
 | 
			
		||||
	public static boolean isMainThread(LuaThread r) {		
 | 
			
		||||
		return r == main_thread;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Set the globals of the current thread.
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * This must be done once before any other code executes.
 | 
			
		||||
	 * @param globals The global variables for the main ghread. 
 | 
			
		||||
	 */
 | 
			
		||||
	public static void setGlobals(LuaValue globals) {
 | 
			
		||||
		running_thread.env = globals;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Get the current thread's environment 
 | 
			
		||||
	 * @return {@link LuaValue} containing the global variables of the current thread.
 | 
			
		||||
	 */
 | 
			
		||||
	public static LuaValue getGlobals() {
 | 
			
		||||
		LuaValue e = running_thread.env;
 | 
			
		||||
		return e!=null? e: LuaValue.error("LuaThread.setGlobals() not initialized");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Callback used at the beginning of a call to prepare for possible getfenv/setfenv calls
 | 
			
		||||
	 * @param function Function being called
 | 
			
		||||
	 * @return CallStack which is used to signal the return or a tail-call recursion
 | 
			
		||||
	 * @see DebugLib
 | 
			
		||||
	 */
 | 
			
		||||
	public static final CallStack onCall(LuaFunction function) {
 | 
			
		||||
		CallStack cs = running_thread.callstack;
 | 
			
		||||
		cs.onCall(function);
 | 
			
		||||
		return cs;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the function called as a specific location on the stack.
 | 
			
		||||
	 * @param level 1 for the function calling this one, 2 for the next one.
 | 
			
		||||
	 * @return LuaFunction on the call stack, or null if outside of range of active stack
 | 
			
		||||
	 */
 | 
			
		||||
	public static final LuaFunction getCallstackFunction(int level) {
 | 
			
		||||
		return running_thread.callstack.getFunction(level);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Replace the error function of the currently running thread.
 | 
			
		||||
	 * @param errfunc the new error function to use.
 | 
			
		||||
	 * @return the previous error function.
 | 
			
		||||
	 */
 | 
			
		||||
	public static LuaValue setErrorFunc(LuaValue errfunc) {
 | 
			
		||||
		LuaValue prev = running_thread.err;
 | 
			
		||||
		running_thread.err = errfunc;
 | 
			
		||||
		return prev;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Yield the current thread with arguments 
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param args The arguments to send as return values to {@link #resume(Varargs)}
 | 
			
		||||
	 * @return {@link Varargs} provided as arguments to {@link #resume(Varargs)}
 | 
			
		||||
	 */
 | 
			
		||||
	public static Varargs yield(Varargs args) {
 | 
			
		||||
		State s = running_thread.state;
 | 
			
		||||
		if (s.function == null)
 | 
			
		||||
			throw new LuaError("cannot yield main thread");
 | 
			
		||||
		return s.lua_yield(args);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Start or resume this thread 
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param args The arguments to send as return values to {@link #yield(Varargs)}
 | 
			
		||||
	 * @return {@link Varargs} provided as arguments to {@link #yield(Varargs)}
 | 
			
		||||
	 */
 | 
			
		||||
	public Varargs resume(Varargs args) {
 | 
			
		||||
		if (this.state.status > STATUS_SUSPENDED)
 | 
			
		||||
			return LuaValue.varargsOf(LuaValue.FALSE, 
 | 
			
		||||
					LuaValue.valueOf("cannot resume "+LuaThread.STATUS_NAMES[this.state.status]+" coroutine"));
 | 
			
		||||
		return state.lua_resume(this, args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* DAN200 START */
 | 
			
		||||
    public void addChild( LuaThread thread ) {
 | 
			
		||||
        this.children.addElement( new WeakReference( thread ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Varargs abandon() {
 | 
			
		||||
        if( this.state.status > STATUS_SUSPENDED ) {
 | 
			
		||||
            return LuaValue.varargsOf( LuaValue.FALSE, LuaValue.valueOf( "cannot abandon " + STATUS_NAMES[this.state.status] + " coroutine" ) );
 | 
			
		||||
        } else {
 | 
			
		||||
            this.state.lua_abandon( this );
 | 
			
		||||
 | 
			
		||||
            Enumeration it = this.children.elements();
 | 
			
		||||
            while( it.hasMoreElements() ) {
 | 
			
		||||
                WeakReference ref = (WeakReference)it.nextElement();
 | 
			
		||||
                LuaThread thread = (LuaThread)ref.get();
 | 
			
		||||
                if(thread != null && !thread.getStatus().equals("dead")) {
 | 
			
		||||
                    thread.abandon();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.children.removeAllElements();
 | 
			
		||||
            return LuaValue.varargsOf( new LuaValue[] { LuaValue.TRUE } );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    /* DAN200 END */
 | 
			
		||||
 | 
			
		||||
	static class State implements Runnable {
 | 
			
		||||
		final WeakReference lua_thread;
 | 
			
		||||
		final LuaValue function;
 | 
			
		||||
		Varargs args = LuaValue.NONE;
 | 
			
		||||
		Varargs result = LuaValue.NONE;
 | 
			
		||||
		String error = null;
 | 
			
		||||
		int status = LuaThread.STATUS_INITIAL;
 | 
			
		||||
        /* DAN200 START */
 | 
			
		||||
        boolean abandoned = false;
 | 
			
		||||
        /* DAN200 END */
 | 
			
		||||
 | 
			
		||||
		State(LuaThread lua_thread, LuaValue function) {
 | 
			
		||||
			this.lua_thread = new WeakReference(lua_thread);
 | 
			
		||||
			this.function = function;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public synchronized void run() {
 | 
			
		||||
			try {
 | 
			
		||||
				Varargs a = this.args;
 | 
			
		||||
				this.args = LuaValue.NONE;
 | 
			
		||||
				this.result = function.invoke(a);
 | 
			
		||||
			} catch (Throwable t) {
 | 
			
		||||
				this.error = t.getMessage();
 | 
			
		||||
			} finally {
 | 
			
		||||
				this.status = LuaThread.STATUS_DEAD;
 | 
			
		||||
				this.notify();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		synchronized Varargs lua_resume(LuaThread new_thread, Varargs args) {
 | 
			
		||||
			LuaThread previous_thread = LuaThread.running_thread;
 | 
			
		||||
			try {
 | 
			
		||||
				LuaThread.running_thread = new_thread;
 | 
			
		||||
				this.args = args;
 | 
			
		||||
				if (this.status == STATUS_INITIAL) {
 | 
			
		||||
					this.status = STATUS_RUNNING; 
 | 
			
		||||
					new Thread(this, "Coroutine-"+(++coroutine_count)).start();
 | 
			
		||||
				} else {
 | 
			
		||||
					this.notify();
 | 
			
		||||
				}
 | 
			
		||||
				previous_thread.state.status = STATUS_NORMAL;
 | 
			
		||||
				this.status = STATUS_RUNNING;
 | 
			
		||||
				this.wait();
 | 
			
		||||
				return (this.error != null? 
 | 
			
		||||
					LuaValue.varargsOf(LuaValue.FALSE, LuaValue.valueOf(this.error)):
 | 
			
		||||
					LuaValue.varargsOf(LuaValue.TRUE, this.result));
 | 
			
		||||
			} catch (InterruptedException ie) {
 | 
			
		||||
				throw new OrphanedThread();
 | 
			
		||||
			} finally {
 | 
			
		||||
				running_thread = previous_thread;
 | 
			
		||||
				running_thread.state.status =STATUS_RUNNING;
 | 
			
		||||
				this.args = LuaValue.NONE;
 | 
			
		||||
				this.result = LuaValue.NONE;
 | 
			
		||||
				this.error = null;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		synchronized Varargs lua_yield(Varargs args) {
 | 
			
		||||
			try {
 | 
			
		||||
				this.result = args;
 | 
			
		||||
				this.status = STATUS_SUSPENDED;
 | 
			
		||||
				this.notify();
 | 
			
		||||
				do {
 | 
			
		||||
					this.wait(thread_orphan_check_interval);
 | 
			
		||||
                    /* DAN200 START */
 | 
			
		||||
					//if (this.lua_thread.get() == null) {
 | 
			
		||||
                    if( this.abandoned || this.lua_thread.get() == null ) {
 | 
			
		||||
                    /* DAN200 END */
 | 
			
		||||
						this.status = STATUS_DEAD;
 | 
			
		||||
						throw new OrphanedThread();
 | 
			
		||||
					}
 | 
			
		||||
				} while (this.status == STATUS_SUSPENDED);
 | 
			
		||||
				return this.args;
 | 
			
		||||
			} catch (InterruptedException ie) {
 | 
			
		||||
				this.status = STATUS_DEAD;
 | 
			
		||||
				throw new OrphanedThread();
 | 
			
		||||
			} finally {
 | 
			
		||||
				this.args = LuaValue.NONE;
 | 
			
		||||
				this.result = LuaValue.NONE;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* DAN200 START */
 | 
			
		||||
        synchronized void lua_abandon(LuaThread thread) {
 | 
			
		||||
            LuaThread current = LuaThread.running_thread;
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                current.state.status = STATUS_NORMAL;
 | 
			
		||||
                this.abandoned = true;
 | 
			
		||||
                if(this.status == STATUS_INITIAL) {
 | 
			
		||||
                    this.status = STATUS_DEAD;
 | 
			
		||||
                } else {
 | 
			
		||||
                    this.notify();
 | 
			
		||||
                    this.wait();
 | 
			
		||||
                }
 | 
			
		||||
            } catch (InterruptedException var7) {
 | 
			
		||||
                this.status = STATUS_DEAD;
 | 
			
		||||
            } finally {
 | 
			
		||||
                current.state.status = STATUS_RUNNING;
 | 
			
		||||
                this.args = LuaValue.NONE;
 | 
			
		||||
                this.result = LuaValue.NONE;
 | 
			
		||||
                this.error = null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        /* DAN200 END */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static class CallStack {
 | 
			
		||||
		final LuaFunction[]     functions     = new LuaFunction[MAX_CALLSTACK];
 | 
			
		||||
		int                     calls         = 0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Method to indicate the start of a call
 | 
			
		||||
		 * @see DebugLib
 | 
			
		||||
		 */
 | 
			
		||||
		final void onCall(LuaFunction function) {
 | 
			
		||||
			functions[calls++] = function;
 | 
			
		||||
			if (DebugLib.DEBUG_ENABLED) 
 | 
			
		||||
				DebugLib.debugOnCall(running_thread, calls, function);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		/**
 | 
			
		||||
		 * Method to signal the end of a call
 | 
			
		||||
		 * @see DebugLib
 | 
			
		||||
		 */
 | 
			
		||||
		public final void onReturn() {
 | 
			
		||||
			functions[--calls] = null;
 | 
			
		||||
			if (DebugLib.DEBUG_ENABLED) 
 | 
			
		||||
				DebugLib.debugOnReturn(running_thread, calls);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		/**
 | 
			
		||||
		 * Get number of calls in stack
 | 
			
		||||
		 * @return number of calls in current call stack
 | 
			
		||||
		 * @see DebugLib
 | 
			
		||||
		 */
 | 
			
		||||
		public final int getCallstackDepth() {
 | 
			
		||||
			return calls;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/** 
 | 
			
		||||
		 * Get the function at a particular level of the stack.
 | 
			
		||||
		 * @param level # of levels back from the top of the stack.
 | 
			
		||||
		 * @return LuaFunction, or null if beyond the stack limits.
 | 
			
		||||
		 */
 | 
			
		||||
		LuaFunction getFunction(int level) {
 | 
			
		||||
			return level>0 && level<=calls? functions[calls-level]: null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,126 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class LuaUserdata extends LuaValue {
 | 
			
		||||
	
 | 
			
		||||
	public final Object m_instance;
 | 
			
		||||
	public LuaValue m_metatable;
 | 
			
		||||
	
 | 
			
		||||
	public LuaUserdata(Object obj) {
 | 
			
		||||
		m_instance = obj;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaUserdata(Object obj, LuaValue metatable) {
 | 
			
		||||
		m_instance = obj;
 | 
			
		||||
		m_metatable = metatable;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String tojstring() {
 | 
			
		||||
		return String.valueOf(m_instance);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int type() {
 | 
			
		||||
		return LuaValue.TUSERDATA;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public String typename() {
 | 
			
		||||
		return "userdata";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int hashCode() {
 | 
			
		||||
		return m_instance.hashCode();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Object userdata() {
 | 
			
		||||
		return m_instance;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isuserdata()                        { return true; }
 | 
			
		||||
	public boolean isuserdata(Class c)                 { return c.isAssignableFrom(m_instance.getClass()); }
 | 
			
		||||
	public Object  touserdata()                        { return m_instance; }
 | 
			
		||||
	public Object  touserdata(Class c)                 { return c.isAssignableFrom(m_instance.getClass())? m_instance: null; }
 | 
			
		||||
	public Object  optuserdata(Object defval)          { return m_instance; }
 | 
			
		||||
	public Object optuserdata(Class c, Object defval) {
 | 
			
		||||
		if (!c.isAssignableFrom(m_instance.getClass()))
 | 
			
		||||
			typerror(c.getName());
 | 
			
		||||
		return m_instance;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue getmetatable() {
 | 
			
		||||
		return m_metatable;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue setmetatable(LuaValue metatable) {
 | 
			
		||||
		this.m_metatable = metatable;
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Object checkuserdata() {
 | 
			
		||||
		return m_instance;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Object checkuserdata(Class c) { 
 | 
			
		||||
		if ( c.isAssignableFrom(m_instance.getClass()) )
 | 
			
		||||
			return m_instance;		
 | 
			
		||||
		return typerror(c.getName());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue get( LuaValue key ) {
 | 
			
		||||
		return m_metatable!=null? gettable(this,key): NIL;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void set( LuaValue key, LuaValue value ) {
 | 
			
		||||
		if ( m_metatable==null || ! settable(this,key,value) )
 | 
			
		||||
			error( "cannot set "+key+" for userdata" );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean equals( Object val ) {
 | 
			
		||||
		if ( this == val )
 | 
			
		||||
			return true;
 | 
			
		||||
		if ( ! (val instanceof LuaUserdata) )
 | 
			
		||||
			return false;
 | 
			
		||||
		LuaUserdata u = (LuaUserdata) val;
 | 
			
		||||
		return m_instance.equals(u.m_instance);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// equality w/ metatable processing
 | 
			
		||||
	public LuaValue eq( LuaValue val )     { return eq_b(val)? TRUE: FALSE; } 
 | 
			
		||||
	public boolean eq_b( LuaValue val ) { 
 | 
			
		||||
		if ( val.raweq(this) ) return true;
 | 
			
		||||
		if ( m_metatable == null || !val.isuserdata() ) return false;
 | 
			
		||||
		LuaValue valmt = val.getmetatable();
 | 
			
		||||
		return valmt!=null && LuaValue.eqmtcall(this, m_metatable, val, valmt); 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// equality w/o metatable processing
 | 
			
		||||
	public boolean raweq( LuaValue val )      { return val.raweq(this); }
 | 
			
		||||
	public boolean raweq( LuaUserdata val )   {
 | 
			
		||||
		return this == val || (m_metatable == val.m_metatable && m_instance.equals(val.m_instance)); 
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// __eq metatag processing
 | 
			
		||||
	public boolean eqmt( LuaValue val )    { 
 | 
			
		||||
		return m_metatable!=null && val.isuserdata()? LuaValue.eqmtcall(this, m_metatable, val, val.getmetatable()): false; 
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,44 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Copyright (c) 2012 Luaj.org. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * {@link java.lang.Error} sublcass that indicates a lua thread that is no
 | 
			
		||||
 * longer referenced has been detected.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The java thread in which this is thrown should correspond to a
 | 
			
		||||
 * {@link LuaThread} being used as a coroutine that could not possibly be
 | 
			
		||||
 * resumed again because there are no more references to the LuaThread with
 | 
			
		||||
 * which it is associated. Rather than locking up resources forever, this error
 | 
			
		||||
 * is thrown, and should fall through all the way to the thread's {@link Thread.run}() method.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Java code mixed with the luaj vm should not catch this error because it may
 | 
			
		||||
 * occur when the coroutine is not running, so any processing done during error
 | 
			
		||||
 * handling could break the thread-safety of the application because other lua
 | 
			
		||||
 * processing could be going on in a different thread.
 | 
			
		||||
 */
 | 
			
		||||
public class OrphanedThread extends Error {
 | 
			
		||||
 | 
			
		||||
	public OrphanedThread() {
 | 
			
		||||
		super("orphaned thread");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,417 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
import java.io.ByteArrayOutputStream;
 | 
			
		||||
import java.io.PrintStream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Debug helper class to pretty-print lua bytecodes. 
 | 
			
		||||
 * @see Prototype
 | 
			
		||||
 * @see LuaClosure 
 | 
			
		||||
 */
 | 
			
		||||
public class Print extends Lua {
 | 
			
		||||
 | 
			
		||||
	/** opcode names */
 | 
			
		||||
	private static final String STRING_FOR_NULL = "null";
 | 
			
		||||
	public static PrintStream ps = System.out;
 | 
			
		||||
 | 
			
		||||
	public static final String[] OPNAMES = {
 | 
			
		||||
		  "MOVE",
 | 
			
		||||
		  "LOADK",
 | 
			
		||||
		  "LOADBOOL",
 | 
			
		||||
		  "LOADNIL",
 | 
			
		||||
		  "GETUPVAL",
 | 
			
		||||
		  "GETGLOBAL",
 | 
			
		||||
		  "GETTABLE",
 | 
			
		||||
		  "SETGLOBAL",
 | 
			
		||||
		  "SETUPVAL",
 | 
			
		||||
		  "SETTABLE",
 | 
			
		||||
		  "NEWTABLE",
 | 
			
		||||
		  "SELF",
 | 
			
		||||
		  "ADD",
 | 
			
		||||
		  "SUB",
 | 
			
		||||
		  "MUL",
 | 
			
		||||
		  "DIV",
 | 
			
		||||
		  "MOD",
 | 
			
		||||
		  "POW",
 | 
			
		||||
		  "UNM",
 | 
			
		||||
		  "NOT",
 | 
			
		||||
		  "LEN",
 | 
			
		||||
		  "CONCAT",
 | 
			
		||||
		  "JMP",
 | 
			
		||||
		  "EQ",
 | 
			
		||||
		  "LT",
 | 
			
		||||
		  "LE",
 | 
			
		||||
		  "TEST",
 | 
			
		||||
		  "TESTSET",
 | 
			
		||||
		  "CALL",
 | 
			
		||||
		  "TAILCALL",
 | 
			
		||||
		  "RETURN",
 | 
			
		||||
		  "FORLOOP",
 | 
			
		||||
		  "FORPREP",
 | 
			
		||||
		  "TFORLOOP",
 | 
			
		||||
		  "SETLIST",
 | 
			
		||||
		  "CLOSE",
 | 
			
		||||
		  "CLOSURE",
 | 
			
		||||
		  "VARARG",
 | 
			
		||||
		  null,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	static void printString(PrintStream ps, final LuaString s) {
 | 
			
		||||
		
 | 
			
		||||
		ps.print('"');
 | 
			
		||||
		for (int i = 0, n = s.m_length; i < n; i++) {
 | 
			
		||||
			int c = s.m_bytes[s.m_offset+i];
 | 
			
		||||
			if ( c >= ' ' && c <= '~' && c != '\"' && c != '\\' )
 | 
			
		||||
				ps.print((char) c);
 | 
			
		||||
			else {
 | 
			
		||||
				switch (c) {
 | 
			
		||||
					case '"':
 | 
			
		||||
						ps.print("\\\"");
 | 
			
		||||
						break;
 | 
			
		||||
					case '\\':
 | 
			
		||||
						ps.print("\\\\");
 | 
			
		||||
						break;
 | 
			
		||||
					case 0x0007: /* bell */
 | 
			
		||||
						ps.print("\\a");
 | 
			
		||||
						break;
 | 
			
		||||
					case '\b': /* backspace */
 | 
			
		||||
						ps.print("\\b");
 | 
			
		||||
						break;
 | 
			
		||||
					case '\f':  /* form feed */
 | 
			
		||||
						ps.print("\\f");
 | 
			
		||||
						break;
 | 
			
		||||
					case '\t':  /* tab */
 | 
			
		||||
						ps.print("\\t");
 | 
			
		||||
						break;
 | 
			
		||||
					case '\r': /* carriage return */
 | 
			
		||||
						ps.print("\\r");
 | 
			
		||||
						break;
 | 
			
		||||
					case '\n': /* newline */
 | 
			
		||||
						ps.print("\\n");
 | 
			
		||||
						break;
 | 
			
		||||
					case 0x000B: /* vertical tab */
 | 
			
		||||
						ps.print("\\v");
 | 
			
		||||
						break;
 | 
			
		||||
					default:
 | 
			
		||||
						ps.print('\\');
 | 
			
		||||
						ps.print(Integer.toString(1000 + 0xff&c).substring(1));
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		ps.print('"');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static void printValue( PrintStream ps, LuaValue v ) {
 | 
			
		||||
		switch ( v.type() ) {
 | 
			
		||||
		case LuaValue.TSTRING: printString( ps, (LuaString) v ); break;
 | 
			
		||||
		default: ps.print( v.tojstring() );
 | 
			
		||||
		
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	static void printConstant(PrintStream ps, Prototype f, int i) {
 | 
			
		||||
		printValue( ps, f.k[i] );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Print the code in a prototype
 | 
			
		||||
	 * @param f the {@link Prototype}
 | 
			
		||||
	 */
 | 
			
		||||
	public static void printCode(Prototype f) {
 | 
			
		||||
		int[] code = f.code;
 | 
			
		||||
		int pc, n = code.length;
 | 
			
		||||
		for (pc = 0; pc < n; pc++) {
 | 
			
		||||
			printOpCode(f, pc);
 | 
			
		||||
			ps.println();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Print an opcode in a prototype
 | 
			
		||||
	 * @param f the {@link Prototype}
 | 
			
		||||
	 * @param pc the program counter to look up and print
 | 
			
		||||
	 */
 | 
			
		||||
	public static void printOpCode(Prototype f, int pc) {
 | 
			
		||||
		printOpCode(ps,f,pc);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Print an opcode in a prototype
 | 
			
		||||
	 * @param ps the {@link PrintStream} to print to
 | 
			
		||||
	 * @param f the {@link Prototype}
 | 
			
		||||
	 * @param pc the program counter to look up and print
 | 
			
		||||
	 */
 | 
			
		||||
	public static void printOpCode(PrintStream ps, Prototype f, int pc) {
 | 
			
		||||
		int[] code = f.code;
 | 
			
		||||
		int i = code[pc];
 | 
			
		||||
		int o = GET_OPCODE(i);
 | 
			
		||||
		int a = GETARG_A(i);
 | 
			
		||||
		int b = GETARG_B(i);
 | 
			
		||||
		int c = GETARG_C(i);
 | 
			
		||||
		int bx = GETARG_Bx(i);
 | 
			
		||||
		int sbx = GETARG_sBx(i);
 | 
			
		||||
		int line = getline(f, pc);
 | 
			
		||||
		ps.print("  " + (pc + 1) + "  ");
 | 
			
		||||
		if (line > 0)
 | 
			
		||||
			ps.print("[" + line + "]  ");
 | 
			
		||||
		else
 | 
			
		||||
			ps.print("[-]  ");
 | 
			
		||||
		ps.print(OPNAMES[o] + "  ");
 | 
			
		||||
		switch (getOpMode(o)) {
 | 
			
		||||
		case iABC:
 | 
			
		||||
			ps.print( a );
 | 
			
		||||
			if (getBMode(o) != OpArgN)
 | 
			
		||||
				ps.print(" "+(ISK(b) ? (-1 - INDEXK(b)) : b));
 | 
			
		||||
			if (getCMode(o) != OpArgN)
 | 
			
		||||
				ps.print(" "+(ISK(c) ? (-1 - INDEXK(c)) : c));
 | 
			
		||||
			break;
 | 
			
		||||
		case iABx:
 | 
			
		||||
			if (getBMode(o) == OpArgK) {
 | 
			
		||||
				ps.print(a + " " + (-1 - bx));
 | 
			
		||||
			} else {
 | 
			
		||||
				ps.print(a + " " + (bx));
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case iAsBx:
 | 
			
		||||
			if (o == OP_JMP)
 | 
			
		||||
				ps.print( sbx );
 | 
			
		||||
			else
 | 
			
		||||
				ps.print(a + " " + sbx);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		switch (o) {
 | 
			
		||||
		case OP_LOADK:
 | 
			
		||||
			ps.print("  ; ");
 | 
			
		||||
			printConstant(ps, f, bx);
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_GETUPVAL:
 | 
			
		||||
		case OP_SETUPVAL:
 | 
			
		||||
			ps.print("  ; ");
 | 
			
		||||
			if ( f.upvalues.length > b )
 | 
			
		||||
				printValue(ps, f.upvalues[b]);
 | 
			
		||||
			else
 | 
			
		||||
				ps.print( "-" );
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_GETGLOBAL:
 | 
			
		||||
		case OP_SETGLOBAL:
 | 
			
		||||
			ps.print("  ; ");
 | 
			
		||||
			printConstant( ps, f, bx );
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_GETTABLE:
 | 
			
		||||
		case OP_SELF:
 | 
			
		||||
			if (ISK(c)) {
 | 
			
		||||
				ps.print("  ; ");
 | 
			
		||||
				printConstant(ps, f, INDEXK(c));
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_SETTABLE:
 | 
			
		||||
		case OP_ADD:
 | 
			
		||||
		case OP_SUB:
 | 
			
		||||
		case OP_MUL:
 | 
			
		||||
		case OP_DIV:
 | 
			
		||||
		case OP_POW:
 | 
			
		||||
		case OP_EQ:
 | 
			
		||||
		case OP_LT:
 | 
			
		||||
		case OP_LE:
 | 
			
		||||
			if (ISK(b) || ISK(c)) {
 | 
			
		||||
				ps.print("  ; ");
 | 
			
		||||
				if (ISK(b))
 | 
			
		||||
					printConstant(ps, f, INDEXK(b));
 | 
			
		||||
				else
 | 
			
		||||
					ps.print("-");
 | 
			
		||||
				ps.print(" ");
 | 
			
		||||
				if (ISK(c))
 | 
			
		||||
					printConstant(ps, f, INDEXK(c));
 | 
			
		||||
				else
 | 
			
		||||
					ps.print("-");
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_JMP:
 | 
			
		||||
		case OP_FORLOOP:
 | 
			
		||||
		case OP_FORPREP:
 | 
			
		||||
			ps.print("  ; to " + (sbx + pc + 2));
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_CLOSURE:
 | 
			
		||||
			ps.print("  ; " + f.p[bx].getClass().getName());
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_SETLIST:
 | 
			
		||||
			if (c == 0)
 | 
			
		||||
				ps.print("  ; " + ((int) code[++pc]));
 | 
			
		||||
			else
 | 
			
		||||
				ps.print("  ; " + ((int) c));
 | 
			
		||||
			break;
 | 
			
		||||
		case OP_VARARG:
 | 
			
		||||
			ps.print( "  ; is_vararg="+ f.is_vararg );
 | 
			
		||||
			break;			
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static int getline(Prototype f, int pc) {
 | 
			
		||||
		return pc>0 && f.lineinfo!=null && pc<f.lineinfo.length? f.lineinfo[pc]: -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static void printHeader(Prototype f) {
 | 
			
		||||
		String s = String.valueOf(f.source);
 | 
			
		||||
		if (s.startsWith("@") || s.startsWith("="))
 | 
			
		||||
			s = s.substring(1);
 | 
			
		||||
		else if ("\033Lua".equals(s))
 | 
			
		||||
			s = "(bstring)";
 | 
			
		||||
		else
 | 
			
		||||
			s = "(string)";
 | 
			
		||||
		String a = (f.linedefined == 0) ? "main" : "function";
 | 
			
		||||
		ps.print("\n%" + a + " <" + s + ":" + f.linedefined + ","
 | 
			
		||||
				+ f.lastlinedefined + "> (" + f.code.length + " instructions, "
 | 
			
		||||
				+ f.code.length * 4 + " bytes at " + id(f) + ")\n");
 | 
			
		||||
		ps.print(f.numparams + " param, " + f.maxstacksize + " slot, "
 | 
			
		||||
				+ f.upvalues.length + " upvalue, ");
 | 
			
		||||
		ps.print(f.locvars.length + " local, " + f.k.length
 | 
			
		||||
				+ " constant, " + f.p.length + " function\n");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static void printConstants(Prototype f) {
 | 
			
		||||
		int i, n = f.k.length;
 | 
			
		||||
		ps.print("constants (" + n + ") for " + id(f) + ":\n");
 | 
			
		||||
		for (i = 0; i < n; i++) {
 | 
			
		||||
			ps.print("  " + (i + 1) + "  ");
 | 
			
		||||
			printValue( ps, f.k[i] );
 | 
			
		||||
			ps.print( "\n");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static void printLocals(Prototype f) {
 | 
			
		||||
		int i, n = f.locvars.length;
 | 
			
		||||
		ps.print("locals (" + n + ") for " + id(f) + ":\n");
 | 
			
		||||
		for (i = 0; i < n; i++) {
 | 
			
		||||
			ps.println("  "+i+"  "+f.locvars[i].varname+" "+(f.locvars[i].startpc+1)+" "+(f.locvars[i].endpc+1));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static void printUpValues(Prototype f) {
 | 
			
		||||
		int i, n = f.upvalues.length;
 | 
			
		||||
		ps.print("upvalues (" + n + ") for " + id(f) + ":\n");
 | 
			
		||||
		for (i = 0; i < n; i++) {
 | 
			
		||||
			ps.print("  " + i + "  " + f.upvalues[i] + "\n");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static void print(Prototype p) {
 | 
			
		||||
		printFunction(p, true);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void printFunction(Prototype f, boolean full) {
 | 
			
		||||
		int i, n = f.p.length;
 | 
			
		||||
		printHeader(f);
 | 
			
		||||
		printCode(f);
 | 
			
		||||
		if (full) {
 | 
			
		||||
			printConstants(f);
 | 
			
		||||
			printLocals(f);
 | 
			
		||||
			printUpValues(f);
 | 
			
		||||
		}
 | 
			
		||||
		for (i = 0; i < n; i++)
 | 
			
		||||
			printFunction(f.p[i], full);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static void format( String s, int maxcols ) {
 | 
			
		||||
		int n = s.length();
 | 
			
		||||
		if ( n > maxcols )
 | 
			
		||||
			ps.print( s.substring(0,maxcols) );
 | 
			
		||||
		else {
 | 
			
		||||
			ps.print( s );
 | 
			
		||||
			for ( int i=maxcols-n; --i>=0; )
 | 
			
		||||
				ps.print( ' ' );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static String id(Prototype f) {
 | 
			
		||||
		return "Proto";
 | 
			
		||||
	}
 | 
			
		||||
	private void _assert(boolean b) {
 | 
			
		||||
		if ( !b ) 
 | 
			
		||||
			throw new NullPointerException("_assert failed");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Print the state of a {@link LuaClosure} that is being executed
 | 
			
		||||
	 * @param cl the {@link LuaClosure} 
 | 
			
		||||
	 * @param pc the program counter
 | 
			
		||||
	 * @param stack the stack of {@link LuaValue}
 | 
			
		||||
	 * @param top the top of the stack
 | 
			
		||||
	 * @param varargs any {@link Varargs} value that may apply
 | 
			
		||||
	 */
 | 
			
		||||
	public static void printState(LuaClosure cl, int pc, LuaValue[] stack, int top, Varargs varargs) {
 | 
			
		||||
		// print opcode into buffer
 | 
			
		||||
		PrintStream previous = ps;
 | 
			
		||||
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
 | 
			
		||||
		ps = new PrintStream( baos );
 | 
			
		||||
		printOpCode( cl.p, pc );
 | 
			
		||||
		ps.flush();
 | 
			
		||||
		ps.close();
 | 
			
		||||
		ps = previous;
 | 
			
		||||
		format( baos.toString(), 50 );
 | 
			
		||||
 | 
			
		||||
		// print stack
 | 
			
		||||
		ps.print('[');
 | 
			
		||||
		for ( int i=0; i<stack.length; i++ ) {
 | 
			
		||||
			LuaValue v = stack[i];
 | 
			
		||||
			if ( v == null ) 
 | 
			
		||||
				ps.print(STRING_FOR_NULL);
 | 
			
		||||
			else switch ( v.type() ) {
 | 
			
		||||
			case LuaValue.TSTRING: 
 | 
			
		||||
				LuaString s = v.checkstring();
 | 
			
		||||
				ps.print( s.length() < 48?
 | 
			
		||||
						s.tojstring():
 | 
			
		||||
						s.substring(0, 32).tojstring()+"...+"+(s.length()-32)+"b");					
 | 
			
		||||
				break;
 | 
			
		||||
			case LuaValue.TFUNCTION:
 | 
			
		||||
				ps.print( ( v instanceof LuaClosure )?
 | 
			
		||||
					((LuaClosure)v).p.toString(): v.tojstring() );
 | 
			
		||||
				break;
 | 
			
		||||
			case LuaValue.TUSERDATA:
 | 
			
		||||
				Object o = v.touserdata();
 | 
			
		||||
				if ( o != null ) {
 | 
			
		||||
					String n = o.getClass().getName();
 | 
			
		||||
					n = n.substring(n.lastIndexOf('.')+1);
 | 
			
		||||
					ps.print( n+": "+Integer.toHexString(o.hashCode()) );
 | 
			
		||||
				} else {
 | 
			
		||||
					ps.print( v.toString() );
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				ps.print(v.tojstring());
 | 
			
		||||
			}
 | 
			
		||||
			if ( i+1 == top )
 | 
			
		||||
				ps.print(']');
 | 
			
		||||
			ps.print( " | " );
 | 
			
		||||
		}
 | 
			
		||||
		ps.print(varargs);
 | 
			
		||||
		ps.println();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,77 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Prototype representing compiled lua code. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This is both a straight translation of the corresponding C type, 
 | 
			
		||||
 * and the main data structure for execution of compiled lua bytecode. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * See documentatation on {@link LuaClosure} for information on how to load 
 | 
			
		||||
 * and execute a {@link Prototype}.
 | 
			
		||||
 * @see LuaClosure
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class Prototype {
 | 
			
		||||
	/* constants used by the function */
 | 
			
		||||
	public LuaValue[] k; 
 | 
			
		||||
	public int[] code;
 | 
			
		||||
	/* functions defined inside the function */
 | 
			
		||||
	public Prototype[] p;
 | 
			
		||||
	/* map from opcodes to source lines */
 | 
			
		||||
	public int[] lineinfo;
 | 
			
		||||
	/* information about local variables */
 | 
			
		||||
	public LocVars[] locvars;
 | 
			
		||||
	/* upvalue names */
 | 
			
		||||
	public LuaString[] upvalues;
 | 
			
		||||
	public LuaString  source;
 | 
			
		||||
	public int nups;
 | 
			
		||||
	public int linedefined;
 | 
			
		||||
	public int lastlinedefined;
 | 
			
		||||
	public int numparams;
 | 
			
		||||
	public int is_vararg;
 | 
			
		||||
	public int maxstacksize;
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	public String toString() {
 | 
			
		||||
		return source + ":" + linedefined+"-"+lastlinedefined;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Get the name of a local variable.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param number the local variable number to look up
 | 
			
		||||
	 * @param pc the program counter
 | 
			
		||||
	 * @return the name, or null if not found
 | 
			
		||||
	 */
 | 
			
		||||
	public LuaString getlocalname(int number, int pc) {
 | 
			
		||||
	  int i;
 | 
			
		||||
	  for (i = 0; i<locvars.length && locvars[i].startpc <= pc; i++) {
 | 
			
		||||
	    if (pc < locvars[i].endpc) {  /* is variable active? */
 | 
			
		||||
	    	number--;
 | 
			
		||||
	      if (number == 0)
 | 
			
		||||
	        return locvars[i].varname;
 | 
			
		||||
	    }
 | 
			
		||||
	  }
 | 
			
		||||
	  return null;  /* not found */
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,97 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2010-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Subclass of {@link Varargs} that represents a lua tail call 
 | 
			
		||||
 * in a Java library function execution environment. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Since Java doesn't have direct support for tail calls, 
 | 
			
		||||
 * any lua function whose {@link Prototype} contains the 
 | 
			
		||||
 * {@link Lua#OP_TAILCALL} bytecode needs a mechanism 
 | 
			
		||||
 * for tail calls when converting lua-bytecode to java-bytecode.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The tail call holds the next function and arguments, 
 | 
			
		||||
 * and the client a call to {@link #eval()} executes the function
 | 
			
		||||
 * repeatedly until the tail calls are completed. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Normally, users of luaj need not concern themselves with the 
 | 
			
		||||
 * details of this mechanism, as it is built into the core 
 | 
			
		||||
 * execution framework. 
 | 
			
		||||
 * @see Prototype 
 | 
			
		||||
 * @see LuaJC
 | 
			
		||||
 */
 | 
			
		||||
public class TailcallVarargs extends Varargs {
 | 
			
		||||
 | 
			
		||||
	private LuaValue func;
 | 
			
		||||
	private Varargs args;
 | 
			
		||||
	private Varargs result;
 | 
			
		||||
	
 | 
			
		||||
	public TailcallVarargs(LuaValue f, Varargs args) {
 | 
			
		||||
		this.func = f;
 | 
			
		||||
		this.args = args;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public TailcallVarargs(LuaValue object, LuaValue methodname, Varargs args) {
 | 
			
		||||
		this.func = object.get(methodname);
 | 
			
		||||
		this.args = LuaValue.varargsOf(object, args);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isTailcall() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Varargs eval() {
 | 
			
		||||
		while ( result == null ) {
 | 
			
		||||
			Varargs r = func.onInvoke(args);
 | 
			
		||||
			if (r.isTailcall()) {
 | 
			
		||||
				TailcallVarargs t = (TailcallVarargs) r;
 | 
			
		||||
				func = t.func;
 | 
			
		||||
				args = t.args;
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				result = r;			
 | 
			
		||||
				func = null;
 | 
			
		||||
				args = null;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue arg( int i ) {
 | 
			
		||||
		if ( result == null )
 | 
			
		||||
			eval();
 | 
			
		||||
		return result.arg(i);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue arg1() {
 | 
			
		||||
		if (result == null)
 | 
			
		||||
			eval();
 | 
			
		||||
		return result.arg1();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int narg() {
 | 
			
		||||
		if (result == null)
 | 
			
		||||
			eval();
 | 
			
		||||
		return result.narg();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,77 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** Upvalue used with Closure formulation
 | 
			
		||||
 * <p>
 | 
			
		||||
 * @see LuaClosure
 | 
			
		||||
 * @see Prototype
 | 
			
		||||
 */
 | 
			
		||||
public final class UpValue {
 | 
			
		||||
 | 
			
		||||
	LuaValue[] array; // initially the stack, becomes a holder 
 | 
			
		||||
	int index;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 *  Create an upvalue relative to a stack
 | 
			
		||||
	 * @param stack the stack
 | 
			
		||||
	 * @param index the index on the stack for the upvalue
 | 
			
		||||
	 */
 | 
			
		||||
	public UpValue( LuaValue[] stack, int index) {
 | 
			
		||||
		this.array = stack;
 | 
			
		||||
		this.index = index;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Convert this upvalue to a Java String
 | 
			
		||||
	 * @return the Java String for this upvalue.
 | 
			
		||||
	 * @see LuaValue#tojstring()
 | 
			
		||||
	 */
 | 
			
		||||
	public String tojstring() {
 | 
			
		||||
		return array[index].tojstring();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the value of the upvalue
 | 
			
		||||
	 * @return the {@link LuaValue} for this upvalue
 | 
			
		||||
	 */
 | 
			
		||||
	public final LuaValue getValue() {
 | 
			
		||||
		return array[index];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the value of the upvalue
 | 
			
		||||
	 * @param the {@link LuaValue} to set it to
 | 
			
		||||
	 */
 | 
			
		||||
	public final void setValue( LuaValue value ) {
 | 
			
		||||
		array[index] = value;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Close this upvalue so it is no longer on the stack
 | 
			
		||||
	 */
 | 
			
		||||
	public final void close() {
 | 
			
		||||
		array = new LuaValue[] { array[index] };
 | 
			
		||||
		index = 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,537 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class to encapsulate varargs values, either as part of a variable argument list, or multiple return values.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To construct varargs, use one of the static methods such as 
 | 
			
		||||
 * {@code LuaValue.varargsOf(LuaValue,LuaValue)}
 | 
			
		||||
 * <p>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Any LuaValue can be used as a stand-in for Varargs, for both calls and return values. 
 | 
			
		||||
 * When doing so, nargs() will return 1 and arg1() or arg(1) will return this.  
 | 
			
		||||
 * This simplifies the case when calling or implementing varargs functions with only 
 | 
			
		||||
 * 1 argument or 1 return value.  
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Varargs can also be derived from other varargs by appending to the front with a call 
 | 
			
		||||
 * such as  {@code LuaValue.varargsOf(LuaValue,Varargs)}
 | 
			
		||||
 * or by taking a portion of the args using {@code Varargs.subargs(int start)}
 | 
			
		||||
 * <p>
 | 
			
		||||
 * @see LuaValue#varargsOf(LuaValue[])
 | 
			
		||||
 * @see LuaValue#varargsOf(LuaValue, Varargs)
 | 
			
		||||
 * @see LuaValue#varargsOf(LuaValue[], Varargs)
 | 
			
		||||
 * @see LuaValue#varargsOf(LuaValue, LuaValue, Varargs)
 | 
			
		||||
 * @see LuaValue#varargsOf(LuaValue[], int, int)
 | 
			
		||||
 * @see LuaValue#varargsOf(LuaValue[], int, int, Varargs)
 | 
			
		||||
 * @see LuaValue#subargs(int)
 | 
			
		||||
 */
 | 
			
		||||
public abstract class Varargs {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the n-th argument value (1-based).
 | 
			
		||||
	 * @param i the index of the argument to get, 1 is the first argument
 | 
			
		||||
	 * @return Value at position i, or LuaValue.NIL if there is none.
 | 
			
		||||
	 * @see Varargs#arg1()
 | 
			
		||||
	 * @see LuaValue#NIL
 | 
			
		||||
	 */
 | 
			
		||||
	abstract public LuaValue arg( int i );
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the number of arguments, or 0 if there are none. 
 | 
			
		||||
	 * @return number of arguments. 
 | 
			
		||||
	 */
 | 
			
		||||
	abstract public int narg();
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the first argument in the list. 
 | 
			
		||||
	 * @return LuaValue which is first in the list, or LuaValue.NIL if there are no values.
 | 
			
		||||
	 * @see Varargs#arg(int)
 | 
			
		||||
	 * @see LuaValue#NIL
 | 
			
		||||
	 */
 | 
			
		||||
	abstract public LuaValue arg1();
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Evaluate any pending tail call and return result.
 | 
			
		||||
	 * @return the evaluated tail call result 
 | 
			
		||||
	 */
 | 
			
		||||
	public Varargs eval() { return this; }
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return true if this is a TailcallVarargs
 | 
			
		||||
	 * @return true if a tail call, false otherwise
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isTailcall() {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -----------------------------------------------------------------------
 | 
			
		||||
	// utilities to get specific arguments and type-check them.
 | 
			
		||||
	// -----------------------------------------------------------------------
 | 
			
		||||
	
 | 
			
		||||
	/** Gets the type of argument {@code i} 
 | 
			
		||||
	 * @param i the index of the argument to convert, 1 is the first argument
 | 
			
		||||
	 * @return int value corresponding to one of the LuaValue integer type values
 | 
			
		||||
	 * @see LuaValue.TNIL
 | 
			
		||||
	 * @see LuaValue.TBOOLEAN
 | 
			
		||||
	 * @see LuaValue.TNUMBER
 | 
			
		||||
	 * @see LuaValue.TSTRING
 | 
			
		||||
	 * @see LuaValue.TTABLE
 | 
			
		||||
	 * @see LuaValue.TFUNCTION
 | 
			
		||||
	 * @see LuaValue.TUSERDATA
 | 
			
		||||
	 * @see LuaValue.TTHREAD
 | 
			
		||||
	 * */
 | 
			
		||||
	public int type(int i)             { return arg(i).type(); }
 | 
			
		||||
	
 | 
			
		||||
	/** Tests if argument i is nil.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return true if the argument is nil or does not exist, false otherwise
 | 
			
		||||
	 * @see LuaValue.TNIL
 | 
			
		||||
	 * */
 | 
			
		||||
	public boolean isnil(int i)        { return arg(i).isnil(); }
 | 
			
		||||
 | 
			
		||||
	/** Tests if argument i is a function.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return true if the argument exists and is a function or closure, false otherwise
 | 
			
		||||
	 * @see LuaValue.TFUNCTION
 | 
			
		||||
	 * */
 | 
			
		||||
	public boolean isfunction(int i)   { return arg(i).isfunction(); }
 | 
			
		||||
 | 
			
		||||
	/** Tests if argument i is a number.
 | 
			
		||||
	 * Since anywhere a number is required, a string can be used that 
 | 
			
		||||
	 * is a number, this will return true for both numbers and 
 | 
			
		||||
	 * strings that can be interpreted as numbers.  
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return true if the argument exists and is a number or 
 | 
			
		||||
	 * string that can be interpreted as a number, false otherwise
 | 
			
		||||
	 * @see LuaValue.TNUMBER
 | 
			
		||||
	 * @see LuaValue.TSTRING
 | 
			
		||||
	 * */
 | 
			
		||||
	public boolean isnumber(int i)     { return arg(i).isnumber(); }
 | 
			
		||||
 | 
			
		||||
	/** Tests if argument i is a string.  
 | 
			
		||||
	 * Since all lua numbers can be used where strings are used, 
 | 
			
		||||
	 * this will return true for both strings and numbers.  
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return true if the argument exists and is a string or number, false otherwise
 | 
			
		||||
	 * @see LuaValue.TNUMBER
 | 
			
		||||
	 * @see LuaValue.TSTRING
 | 
			
		||||
	 * */
 | 
			
		||||
	public boolean isstring(int i)     { return arg(i).isstring(); }
 | 
			
		||||
 | 
			
		||||
	/** Tests if argument i is a table.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return true if the argument exists and is a lua table, false otherwise
 | 
			
		||||
	 * @see LuaValue.TTABLE
 | 
			
		||||
	 * */
 | 
			
		||||
	public boolean istable(int i)      { return arg(i).istable(); }
 | 
			
		||||
 | 
			
		||||
	/** Tests if argument i is a thread.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return true if the argument exists and is a lua thread, false otherwise
 | 
			
		||||
	 * @see LuaValue.TTHREAD
 | 
			
		||||
	 * */
 | 
			
		||||
	public boolean isthread(int i)     { return arg(i).isthread(); }
 | 
			
		||||
 | 
			
		||||
	/** Tests if argument i is a userdata.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return true if the argument exists and is a userdata, false otherwise
 | 
			
		||||
	 * @see LuaValue.TUSERDATA
 | 
			
		||||
	 * */
 | 
			
		||||
	public boolean isuserdata(int i)   { return arg(i).isuserdata(); }
 | 
			
		||||
 | 
			
		||||
	/** Tests if a value exists at argument i.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return true if the argument exists, false otherwise
 | 
			
		||||
	 * */
 | 
			
		||||
	public boolean isvalue(int i)      { return i>0 && i<=narg(); }
 | 
			
		||||
	
 | 
			
		||||
	/** Return argument i as a boolean value, {@code defval} if nil, or throw a LuaError if any other type.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return true if argument i is boolean true, false if it is false, or defval if not supplied or nil 
 | 
			
		||||
	 * @exception LuaError if the argument is not a lua boolean
 | 
			
		||||
	 * */
 | 
			
		||||
	public boolean      optboolean(int i, boolean defval)          { return arg(i).optboolean(defval); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a closure, {@code defval} if nil, or throw a LuaError if any other type.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaClosure if argument i is a closure, or defval if not supplied or nil
 | 
			
		||||
	 * @exception LuaError if the argument is not a lua closure
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaClosure   optclosure(int i, LuaClosure defval)       { return arg(i).optclosure(defval); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a double, {@code defval} if nil, or throw a LuaError if it cannot be converted to one.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return java double value if argument i is a number or string that converts to a number, or defval if not supplied or nil
 | 
			
		||||
	 * @exception LuaError if the argument is not a number
 | 
			
		||||
	 * */
 | 
			
		||||
	public double       optdouble(int i, double defval)            { return arg(i).optdouble(defval); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a function, {@code defval} if nil, or throw a LuaError  if an incompatible type.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaValue that can be called if argument i is lua function or closure, or defval if not supplied or nil
 | 
			
		||||
	 * @exception LuaError if the argument is not a lua function or closure
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaFunction  optfunction(int i, LuaFunction defval)     { return arg(i).optfunction(defval); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java int value, discarding any fractional part, {@code defval} if nil, or throw a LuaError  if not a number.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return int value with fraction discarded and truncated if necessary if argument i is number, or defval if not supplied or nil
 | 
			
		||||
	 * @exception LuaError if the argument is not a number
 | 
			
		||||
	 * */
 | 
			
		||||
	public int          optint(int i, int defval)                  { return arg(i).optint(defval); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java int value, {@code defval} if nil, or throw a LuaError  if not a number or is not representable by a java int.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaInteger value that fits in a java int without rounding, or defval if not supplied or nil
 | 
			
		||||
	 * @exception LuaError if the argument cannot be represented by a java int value
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaInteger   optinteger(int i, LuaInteger defval)       { return arg(i).optinteger(defval); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java long value, discarding any fractional part, {@code defval} if nil, or throw a LuaError  if not a number.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return long value with fraction discarded and truncated if necessary if argument i is number, or defval if not supplied or nil
 | 
			
		||||
	 * @exception LuaError if the argument is not a number
 | 
			
		||||
	 * */
 | 
			
		||||
	public long         optlong(int i, long defval)                { return arg(i).optlong(defval); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a LuaNumber, {@code defval} if nil, or throw a LuaError  if not a number or string that can be converted to a number.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument, or defval if not supplied or nil
 | 
			
		||||
	 * @return LuaNumber if argument i is number or can be converted to a number
 | 
			
		||||
	 * @exception LuaError if the argument is not a number
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaNumber    optnumber(int i, LuaNumber defval)         { return arg(i).optnumber(defval); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java String if a string or number, {@code defval} if nil, or throw a LuaError  if any other type
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return String value if argument i is a string or number, or defval if not supplied or nil
 | 
			
		||||
	 * @exception LuaError if the argument is not a string or number
 | 
			
		||||
	 * */
 | 
			
		||||
	public String       optjstring(int i, String defval)           { return arg(i).optjstring(defval); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a LuaString if a string or number, {@code defval} if nil, or throw a LuaError  if any other type
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaString value if argument i is a string or number, or defval if not supplied or nil
 | 
			
		||||
	 * @exception LuaError if the argument is not a string or number
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaString    optstring(int i, LuaString defval)         { return arg(i).optstring(defval); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a LuaTable if a lua table, {@code defval} if nil, or throw a LuaError  if any other type.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaTable value if a table, or defval if not supplied or nil
 | 
			
		||||
	 * @exception LuaError if the argument is not a lua table
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaTable     opttable(int i, LuaTable defval)           { return arg(i).opttable(defval); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a LuaThread if a lua thread, {@code defval} if nil, or throw a LuaError  if any other type.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaThread value if a thread, or defval if not supplied or nil
 | 
			
		||||
	 * @exception LuaError if the argument is not a lua thread
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaThread    optthread(int i, LuaThread defval)         { return arg(i).optthread(defval); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java Object if a userdata, {@code defval} if nil, or throw a LuaError  if any other type.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return java Object value if argument i is a userdata, or defval if not supplied or nil
 | 
			
		||||
	 * @exception LuaError if the argument is not a userdata
 | 
			
		||||
	 * */
 | 
			
		||||
	public Object       optuserdata(int i, Object defval)          { return arg(i).optuserdata(defval); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java Object if it is a userdata whose instance Class c or a subclass, 
 | 
			
		||||
	 * {@code defval} if nil, or throw a LuaError  if any other type.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @param c the class to which the userdata instance must be assignable
 | 
			
		||||
	 * @return java Object value if argument i is a userdata whose instance Class c or a subclass, or defval if not supplied or nil
 | 
			
		||||
	 * @exception LuaError if the argument is not a userdata or from whose instance c is not assignable
 | 
			
		||||
	 * */
 | 
			
		||||
	public Object       optuserdata(int i, Class c, Object defval) { return arg(i).optuserdata(c,defval); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a LuaValue if it exists, or {@code defval}.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaValue value if the argument exists, defval if not
 | 
			
		||||
	 * @exception LuaError if the argument does not exist.
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaValue     optvalue(int i, LuaValue defval)           { return i>0 && i<=narg()? arg(i): defval; }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a boolean value, or throw an error if any other type.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return true if argument i is boolean true, false if it is false
 | 
			
		||||
	 * @exception LuaError if the argument is not a lua boolean
 | 
			
		||||
	 * */
 | 
			
		||||
	public boolean      checkboolean(int i)          { return arg(i).checkboolean(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a closure, or throw an error if any other type.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaClosure if argument i is a closure.
 | 
			
		||||
	 * @exception LuaError if the argument is not a lua closure
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaClosure   checkclosure(int i)          { return arg(i).checkclosure(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a double, or throw an error if it cannot be converted to one.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return java double value if argument i is a number or string that converts to a number
 | 
			
		||||
	 * @exception LuaError if the argument is not a number
 | 
			
		||||
	 * */
 | 
			
		||||
	public double       checkdouble(int i)           { return arg(i).checknumber().todouble(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a function, or throw an error if an incompatible type.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaValue that can be called if argument i is lua function or closure
 | 
			
		||||
	 * @exception LuaError if the argument is not a lua function or closure
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaValue     checkfunction(int i)         { return arg(i).checkfunction(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java int value, discarding any fractional part, or throw an error if not a number.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return int value with fraction discarded and truncated if necessary if argument i is number
 | 
			
		||||
	 * @exception LuaError if the argument is not a number
 | 
			
		||||
	 * */
 | 
			
		||||
	public int          checkint(int i)              { return arg(i).checknumber().toint(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java int value, or throw an error if not a number or is not representable by a java int.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaInteger value that fits in a java int without rounding
 | 
			
		||||
	 * @exception LuaError if the argument cannot be represented by a java int value
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaInteger   checkinteger(int i)          { return arg(i).checkinteger(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java long value, discarding any fractional part, or throw an error if not a number.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return long value with fraction discarded and truncated if necessary if argument i is number
 | 
			
		||||
	 * @exception LuaError if the argument is not a number
 | 
			
		||||
	 * */
 | 
			
		||||
	public long         checklong(int i)             { return arg(i).checknumber().tolong(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a LuaNumber, or throw an error if not a number or string that can be converted to a number.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaNumber if argument i is number or can be converted to a number
 | 
			
		||||
	 * @exception LuaError if the argument is not a number
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaNumber    checknumber(int i)           { return arg(i).checknumber(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java String if a string or number, or throw an error if any other type
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return String value if argument i is a string or number
 | 
			
		||||
	 * @exception LuaError if the argument is not a string or number
 | 
			
		||||
	 * */
 | 
			
		||||
	public String       checkjstring(int i)          { return arg(i).checkjstring(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a LuaString if a string or number, or throw an error if any other type
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaString value if argument i is a string or number
 | 
			
		||||
	 * @exception LuaError if the argument is not a string or number
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaString    checkstring(int i)           { return arg(i).checkstring(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a LuaTable if a lua table, or throw an error if any other type.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaTable value if a table
 | 
			
		||||
	 * @exception LuaError if the argument is not a lua table
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaTable     checktable(int i)            { return arg(i).checktable(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a LuaThread if a lua thread, or throw an error if any other type.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaThread value if a thread
 | 
			
		||||
	 * @exception LuaError if the argument is not a lua thread
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaThread    checkthread(int i)           { return arg(i).checkthread(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java Object if a userdata, or throw an error if any other type.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return java Object value if argument i is a userdata
 | 
			
		||||
	 * @exception LuaError if the argument is not a userdata
 | 
			
		||||
	 * */
 | 
			
		||||
	public Object       checkuserdata(int i)         { return arg(i).checkuserdata(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java Object if it is a userdata whose instance Class c or a subclass, 
 | 
			
		||||
	 * or throw an error if any other type.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @param c the class to which the userdata instance must be assignable
 | 
			
		||||
	 * @return java Object value if argument i is a userdata whose instance Class c or a subclass
 | 
			
		||||
	 * @exception LuaError if the argument is not a userdata or from whose instance c is not assignable
 | 
			
		||||
	 * */
 | 
			
		||||
	public Object       checkuserdata(int i,Class c) { return arg(i).checkuserdata(c); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a LuaValue if it exists, or throw an error.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaValue value if the argument exists
 | 
			
		||||
	 * @exception LuaError if the argument does not exist.
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaValue     checkvalue(int i)            { return i<=narg()? arg(i): LuaValue.argerror(i,"value expected"); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a LuaValue if it is not nil, or throw an error if it is nil.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return LuaValue value if the argument is not nil
 | 
			
		||||
	 * @exception LuaError if the argument doesn't exist or evaluates to nil.
 | 
			
		||||
	 * */
 | 
			
		||||
	public LuaValue     checknotnil(int i)           { return arg(i).checknotnil(); }
 | 
			
		||||
	
 | 
			
		||||
	/** Return argument i as a LuaValue when a user-supplied assertion passes, or throw an error.
 | 
			
		||||
	 * @param test user supplied assertion to test against
 | 
			
		||||
	 * @param i the index to report in any error message
 | 
			
		||||
	 * @param msg the error message to use when the test fails
 | 
			
		||||
	 * @return LuaValue value if the value of {@code test} is {@code true}
 | 
			
		||||
	 * @exception LuaError if the the value of {@code test} is {@code false}
 | 
			
		||||
	 * */
 | 
			
		||||
	public void         argcheck(boolean test, int i, String msg) { if (!test) LuaValue.argerror(i,msg); }
 | 
			
		||||
	
 | 
			
		||||
	/** Return true if there is no argument or nil at argument i.
 | 
			
		||||
	 * @param i the index of the argument to test, 1 is the first argument
 | 
			
		||||
	 * @return true if argument i contains either no argument or nil
 | 
			
		||||
	 * */
 | 
			
		||||
	public boolean isnoneornil(int i) {
 | 
			
		||||
		return i>narg() || arg(i).isnil();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Convert argument {@code i} to java boolean based on lua rules for boolean evaluation. 
 | 
			
		||||
	 * @param i the index of the argument to convert, 1 is the first argument
 | 
			
		||||
	 * @return {@code false} if argument i is nil or false, otherwise {@code true}
 | 
			
		||||
	 * */
 | 
			
		||||
	public boolean toboolean(int i)           { return arg(i).toboolean(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java byte value, discarding any fractional part and truncating, 
 | 
			
		||||
	 * or 0 if not a number.
 | 
			
		||||
	 * @param i the index of the argument to convert, 1 is the first argument
 | 
			
		||||
	 * @return byte value with fraction discarded and truncated if necessary if argument i is number, otherwise 0
 | 
			
		||||
	 * */
 | 
			
		||||
	public byte    tobyte(int i)              { return arg(i).tobyte(); }
 | 
			
		||||
	
 | 
			
		||||
	/** Return argument i as a java char value, discarding any fractional part and truncating, 
 | 
			
		||||
	 * or 0 if not a number.
 | 
			
		||||
	 * @param i the index of the argument to convert, 1 is the first argument
 | 
			
		||||
	 * @return char value with fraction discarded and truncated if necessary if argument i is number, otherwise 0
 | 
			
		||||
	 * */
 | 
			
		||||
	public char    tochar(int i)              { return arg(i).tochar(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java double value or 0 if not a number.
 | 
			
		||||
	 * @param i the index of the argument to convert, 1 is the first argument
 | 
			
		||||
	 * @return double value if argument i is number, otherwise 0
 | 
			
		||||
	 * */
 | 
			
		||||
	public double  todouble(int i)            { return arg(i).todouble(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java float value, discarding excess fractional part and truncating, 
 | 
			
		||||
	 * or 0 if not a number.
 | 
			
		||||
	 * @param i the index of the argument to convert, 1 is the first argument
 | 
			
		||||
	 * @return float value with excess fraction discarded and truncated if necessary if argument i is number, otherwise 0
 | 
			
		||||
	 * */
 | 
			
		||||
	public float   tofloat(int i)             { return arg(i).tofloat(); }
 | 
			
		||||
	
 | 
			
		||||
	/** Return argument i as a java int value, discarding any fractional part and truncating, 
 | 
			
		||||
	 * or 0 if not a number.
 | 
			
		||||
	 * @param i the index of the argument to convert, 1 is the first argument
 | 
			
		||||
	 * @return int value with fraction discarded and truncated if necessary if argument i is number, otherwise 0
 | 
			
		||||
	 * */
 | 
			
		||||
	public int     toint(int i)               { return arg(i).toint(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java long value, discarding any fractional part and truncating, 
 | 
			
		||||
	 * or 0 if not a number.
 | 
			
		||||
	 * @param i the index of the argument to convert, 1 is the first argument
 | 
			
		||||
	 * @return long value with fraction discarded and truncated if necessary if argument i is number, otherwise 0
 | 
			
		||||
	 * */
 | 
			
		||||
	public long    tolong(int i)              { return arg(i).tolong(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java String based on the type of the argument.
 | 
			
		||||
	 * @param i the index of the argument to convert, 1 is the first argument
 | 
			
		||||
	 * @return String value representing the type
 | 
			
		||||
	 * */
 | 
			
		||||
	public String  tojstring(int i)           { return arg(i).tojstring(); }
 | 
			
		||||
	
 | 
			
		||||
	/** Return argument i as a java short value, discarding any fractional part and truncating, 
 | 
			
		||||
	 * or 0 if not a number.
 | 
			
		||||
	 * @param i the index of the argument to convert, 1 is the first argument
 | 
			
		||||
	 * @return short value with fraction discarded and truncated if necessary if argument i is number, otherwise 0
 | 
			
		||||
	 * */
 | 
			
		||||
	public short   toshort(int i)             { return arg(i).toshort(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java Object if a userdata, or null.
 | 
			
		||||
	 * @param i the index of the argument to convert, 1 is the first argument
 | 
			
		||||
	 * @return java Object value if argument i is a userdata, otherwise null
 | 
			
		||||
	 * */
 | 
			
		||||
	public Object  touserdata(int i)          { return arg(i).touserdata(); }
 | 
			
		||||
 | 
			
		||||
	/** Return argument i as a java Object if it is a userdata whose instance Class c or a subclass, or null.
 | 
			
		||||
	 * @param i the index of the argument to convert, 1 is the first argument
 | 
			
		||||
	 * @param c the class to which the userdata instance must be assignable
 | 
			
		||||
	 * @return java Object value if argument i is a userdata whose instance Class c or a subclass, otherwise null
 | 
			
		||||
	 * */
 | 
			
		||||
	public Object  touserdata(int i,Class c)  { return arg(i).touserdata(c); }
 | 
			
		||||
	
 | 
			
		||||
	/** Convert the list of varargs values to a human readable java String. 
 | 
			
		||||
	 * @return String value in human readable form such as {1,2}. 
 | 
			
		||||
	 */
 | 
			
		||||
	public String tojstring() {
 | 
			
		||||
		Buffer sb = new Buffer();
 | 
			
		||||
		sb.append( "(" );
 | 
			
		||||
		for ( int i=1,n=narg(); i<=n; i++ ) {
 | 
			
		||||
			if (i>1) sb.append( "," );
 | 
			
		||||
			sb.append( arg(i).tojstring() );
 | 
			
		||||
		}
 | 
			
		||||
		sb.append( ")" );
 | 
			
		||||
		return sb.tojstring();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Convert the value or values to a java String using Varargs.tojstring() 
 | 
			
		||||
	 * @return String value in human readable form. 
 | 
			
		||||
	 * @see Varargs#tojstring()
 | 
			
		||||
	 */
 | 
			
		||||
	public String toString() { return tojstring(); }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a {@code Varargs} instance containing arguments starting at index {@code start}
 | 
			
		||||
	 * @param start the index from which to include arguments, where 1 is the first argument.
 | 
			
		||||
	 * @return Varargs containing argument { start, start+1,  ... , narg-start-1 }
 | 
			
		||||
	 */
 | 
			
		||||
	public Varargs subargs(final int start) {
 | 
			
		||||
		int end = narg();
 | 
			
		||||
		switch ( end-start ) {
 | 
			
		||||
		case 0: return arg(start);
 | 
			
		||||
		case 1: return new LuaValue.PairVarargs(arg(start),arg(end));
 | 
			
		||||
		}
 | 
			
		||||
		return end<start? (Varargs) LuaValue.NONE: new SubVarargs(this,start,end); 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Implementation of Varargs for use in the Varargs.subargs() function.
 | 
			
		||||
	 * @see Varargs#subargs(int)
 | 
			
		||||
	 */
 | 
			
		||||
	private static class SubVarargs extends Varargs {
 | 
			
		||||
		private final Varargs v;
 | 
			
		||||
		private final int start;
 | 
			
		||||
		private final int end;
 | 
			
		||||
		public SubVarargs(Varargs varargs, int start, int end) {
 | 
			
		||||
			this.v = varargs;
 | 
			
		||||
			this.start = start;
 | 
			
		||||
			this.end = end;
 | 
			
		||||
		}
 | 
			
		||||
		public LuaValue arg(int i) {
 | 
			
		||||
			i += start-1;
 | 
			
		||||
			return i>=start && i<=end? v.arg(i): LuaValue.NIL;
 | 
			
		||||
		}
 | 
			
		||||
		public LuaValue arg1() {
 | 
			
		||||
			return v.arg(start);
 | 
			
		||||
		}
 | 
			
		||||
		public int narg() {
 | 
			
		||||
			return end+1-start;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,349 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
package org.luaj.vm2;
 | 
			
		||||
 | 
			
		||||
import java.lang.ref.WeakReference;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.lib.TwoArgFunction;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Subclass of {@link LuaTable} that provides weak key and weak value semantics. 
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * Normally these are not created directly, but indirectly when changing the mode 
 | 
			
		||||
 * of a {@link LuaTable} as lua script executes.  
 | 
			
		||||
 * <p>
 | 
			
		||||
 * However, calling the constructors directly when weak tables are required from 
 | 
			
		||||
 * Java will reduce overhead.  
 | 
			
		||||
 */
 | 
			
		||||
public class WeakTable extends LuaTable {
 | 
			
		||||
	private boolean weakkeys,weakvalues;
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Construct a table with weak keys, weak values, or both
 | 
			
		||||
	 * @param weakkeys true to let the table have weak keys
 | 
			
		||||
	 * @param weakvalues true to let the table have weak values
 | 
			
		||||
	 */
 | 
			
		||||
	public WeakTable(boolean weakkeys, boolean weakvalues) {
 | 
			
		||||
		this(weakkeys, weakvalues, 0, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Construct a table with weak keys, weak values, or both, and an initial capacity
 | 
			
		||||
	 * @param weakkeys true to let the table have weak keys
 | 
			
		||||
	 * @param weakvalues true to let the table have weak values
 | 
			
		||||
	 * @param narray capacity of array part
 | 
			
		||||
	 * @param nhash capacity of hash part
 | 
			
		||||
	 */
 | 
			
		||||
	protected WeakTable(boolean weakkeys, boolean weakvalues, int narray, int nhash) {
 | 
			
		||||
		super(narray, nhash);
 | 
			
		||||
		this.weakkeys = weakkeys;
 | 
			
		||||
		this.weakvalues = weakvalues;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Construct a table with weak keys, weak values, or both, and a source of initial data
 | 
			
		||||
	 * @param weakkeys true to let the table have weak keys
 | 
			
		||||
	 * @param weakvalues true to let the table have weak values
 | 
			
		||||
	 * @param source {@link LuaTable} containing the initial elements
 | 
			
		||||
	 */
 | 
			
		||||
	protected WeakTable(boolean weakkeys, boolean weakvalues, LuaTable source) {
 | 
			
		||||
		this(weakkeys, weakvalues, source.getArrayLength(), source.getHashLength());
 | 
			
		||||
		Varargs n;
 | 
			
		||||
		LuaValue k = NIL;
 | 
			
		||||
		while ( !(k = ((n = source.next(k)).arg1())).isnil() )
 | 
			
		||||
			rawset(k, n.arg(2));
 | 
			
		||||
		m_metatable = source.m_metatable;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void presize( int narray ) {
 | 
			
		||||
		super.presize(narray);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Presize capacity of both array and hash parts.
 | 
			
		||||
	 * @param narray capacity of array part
 | 
			
		||||
	 * @param nhash capacity of hash part
 | 
			
		||||
	 */
 | 
			
		||||
	public void presize(int narray, int nhash) {
 | 
			
		||||
		super.presize(narray, nhash);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected int getArrayLength() {
 | 
			
		||||
		return super.getArrayLength();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	protected int getHashLength() {
 | 
			
		||||
		return super.getHashLength();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected LuaTable changemode(boolean weakkeys, boolean weakvalues) {
 | 
			
		||||
		this.weakkeys = weakkeys;
 | 
			
		||||
		this.weakvalues = weakvalues;
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Self-sent message to convert a value to its weak counterpart
 | 
			
		||||
	 * @param value value to convert
 | 
			
		||||
	 * @return {@link LuaValue} that is a strong or weak reference, depending on type of {@code value}
 | 
			
		||||
	 */
 | 
			
		||||
	LuaValue weaken( LuaValue value ) {
 | 
			
		||||
		switch ( value.type() ) {
 | 
			
		||||
			case LuaValue.TFUNCTION:
 | 
			
		||||
			case LuaValue.TTHREAD:
 | 
			
		||||
			case LuaValue.TTABLE:
 | 
			
		||||
				return new WeakValue(value);
 | 
			
		||||
			case LuaValue.TUSERDATA:
 | 
			
		||||
				return new WeakUserdata(value);
 | 
			
		||||
			default:
 | 
			
		||||
				return value;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void rawset( int key, LuaValue value ) {
 | 
			
		||||
		if ( weakvalues )
 | 
			
		||||
			value = weaken( value );
 | 
			
		||||
		super.rawset(key, value);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void rawset( LuaValue key, LuaValue value ) {
 | 
			
		||||
		if ( weakvalues )
 | 
			
		||||
			value = weaken( value );
 | 
			
		||||
		if ( weakkeys ) {
 | 
			
		||||
			switch ( key.type() ) {
 | 
			
		||||
				case LuaValue.TFUNCTION:
 | 
			
		||||
				case LuaValue.TTHREAD:
 | 
			
		||||
				case LuaValue.TTABLE:
 | 
			
		||||
				case LuaValue.TUSERDATA:
 | 
			
		||||
					key = value = new WeakEntry(this, key, value);
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		super.rawset(key, value);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	public LuaValue rawget( int key ) {
 | 
			
		||||
		return super.rawget(key).strongvalue();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue rawget( LuaValue key ) {
 | 
			
		||||
		return super.rawget(key).strongvalue();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Get the hash value for a key 
 | 
			
		||||
	 * key the key to look up 
 | 
			
		||||
	 * */
 | 
			
		||||
	protected LuaValue hashget(LuaValue key) {
 | 
			
		||||
		if ( hashEntries > 0 ) {
 | 
			
		||||
			int i = hashFindSlot(key);
 | 
			
		||||
			if ( hashEntries == 0 )
 | 
			
		||||
				return NIL;
 | 
			
		||||
			LuaValue v = hashValues[i];
 | 
			
		||||
			return v!=null? v: NIL;
 | 
			
		||||
		}
 | 
			
		||||
		return NIL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	// override to remove values for weak keys as we search
 | 
			
		||||
	public int hashFindSlot(LuaValue key) {		
 | 
			
		||||
		int i = ( key.hashCode() & 0x7FFFFFFF ) % hashKeys.length;
 | 
			
		||||
		LuaValue k;
 | 
			
		||||
		while ( ( k = hashKeys[i] ) != null ) {
 | 
			
		||||
			if ( k.isweaknil() ) {
 | 
			
		||||
				hashClearSlot(i);
 | 
			
		||||
				if ( hashEntries == 0 )
 | 
			
		||||
					return 0;
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				if ( k.raweq(key.strongkey()) )
 | 
			
		||||
					return i;
 | 
			
		||||
				i = ( i + 1 ) % hashKeys.length;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return i;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int maxn() {
 | 
			
		||||
		return super.maxn();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the next element after a particular key in the table 
 | 
			
		||||
	 * @return key,value or nil
 | 
			
		||||
	 */
 | 
			
		||||
	public Varargs next( LuaValue key ) {
 | 
			
		||||
		while ( true ) {
 | 
			
		||||
			Varargs n = super.next(key);
 | 
			
		||||
			LuaValue k = n.arg1();
 | 
			
		||||
			if ( k.isnil() )
 | 
			
		||||
				return NIL;
 | 
			
		||||
			LuaValue ks = k.strongkey();
 | 
			
		||||
			LuaValue vs = n.arg(2).strongvalue();
 | 
			
		||||
			if ( ks.isnil() || vs.isnil() ) {
 | 
			
		||||
				super.rawset(k, NIL);
 | 
			
		||||
			} else {
 | 
			
		||||
				return varargsOf(ks,vs);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// ----------------- sort support -----------------------------
 | 
			
		||||
	public void sort(final LuaValue comparator) {
 | 
			
		||||
		super.sort( new TwoArgFunction() {
 | 
			
		||||
			public LuaValue call(LuaValue arg1, LuaValue arg2) {
 | 
			
		||||
				return comparator.call( arg1.strongvalue(), arg2.strongvalue() );
 | 
			
		||||
			}
 | 
			
		||||
		} );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Internal class to implement weak values. 
 | 
			
		||||
	 * @see WeakTable
 | 
			
		||||
	 */
 | 
			
		||||
	static class WeakValue extends LuaValue {
 | 
			
		||||
		final WeakReference ref;
 | 
			
		||||
 | 
			
		||||
		protected WeakValue(LuaValue value) {
 | 
			
		||||
			ref = new WeakReference(value);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public int type() {
 | 
			
		||||
			illegal("type","weak value");
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public String typename() {
 | 
			
		||||
			illegal("typename","weak value");
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public String toString() {
 | 
			
		||||
			return "weak<"+ref.get()+">";
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public LuaValue strongvalue() {
 | 
			
		||||
			Object o = ref.get();
 | 
			
		||||
			return o!=null? (LuaValue)o: NIL;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public boolean raweq(LuaValue rhs) {
 | 
			
		||||
			Object o = ref.get();
 | 
			
		||||
			return o!=null && rhs.raweq((LuaValue)o);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public boolean isweaknil() {
 | 
			
		||||
			return ref.get() == null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Internal class to implement weak userdata values. 
 | 
			
		||||
	 * @see WeakTable
 | 
			
		||||
	 */
 | 
			
		||||
	static final class WeakUserdata extends WeakValue {
 | 
			
		||||
		private final WeakReference ob;
 | 
			
		||||
		private final LuaValue mt;
 | 
			
		||||
 | 
			
		||||
		private WeakUserdata(LuaValue value) {
 | 
			
		||||
			super(value);
 | 
			
		||||
			ob = new WeakReference(value.touserdata());
 | 
			
		||||
			mt = value.getmetatable();
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public LuaValue strongvalue() {
 | 
			
		||||
			Object u = ref.get();
 | 
			
		||||
			if ( u != null )
 | 
			
		||||
				return (LuaValue) u;
 | 
			
		||||
			Object o = ob.get();
 | 
			
		||||
			return o!=null? userdataOf(o,mt): NIL;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public boolean raweq(LuaValue rhs) {
 | 
			
		||||
			if ( ! rhs.isuserdata() )
 | 
			
		||||
				return false;
 | 
			
		||||
			LuaValue v = (LuaValue) ref.get();
 | 
			
		||||
			if ( v != null && v.raweq(rhs) )
 | 
			
		||||
				return true;
 | 
			
		||||
			return rhs.touserdata() == ob.get();
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public boolean isweaknil() {
 | 
			
		||||
			return ob.get() == null || ref.get() == null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Internal class to implement weak table entries. 
 | 
			
		||||
	 * @see WeakTable
 | 
			
		||||
	 */
 | 
			
		||||
	static final class WeakEntry extends LuaValue {
 | 
			
		||||
		final LuaValue weakkey;
 | 
			
		||||
		LuaValue weakvalue;
 | 
			
		||||
		final int keyhash;
 | 
			
		||||
 | 
			
		||||
		private WeakEntry(WeakTable table, LuaValue key, LuaValue weakvalue) {
 | 
			
		||||
			this.weakkey = table.weaken(key);
 | 
			
		||||
			this.keyhash = key.hashCode();
 | 
			
		||||
			this.weakvalue = weakvalue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public LuaValue strongkey() {
 | 
			
		||||
			return weakkey.strongvalue();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// when looking up the value, look in the keys metatable
 | 
			
		||||
		public LuaValue strongvalue() {
 | 
			
		||||
			LuaValue key = weakkey.strongvalue();
 | 
			
		||||
			if ( key.isnil() )
 | 
			
		||||
				return weakvalue = NIL;
 | 
			
		||||
			return weakvalue.strongvalue();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public int type() {
 | 
			
		||||
			return TNONE;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public String typename() {
 | 
			
		||||
			illegal("typename","weak entry");
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public String toString() {
 | 
			
		||||
			return "weak<"+weakkey.strongvalue()+","+strongvalue()+">";
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public int hashCode() {
 | 
			
		||||
			return keyhash;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public boolean raweq(LuaValue rhs) {
 | 
			
		||||
			//return rhs.raweq(weakkey.strongvalue());
 | 
			
		||||
			return weakkey.raweq(rhs);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public boolean isweaknil() {
 | 
			
		||||
			return weakkey.isweaknil() || weakvalue.isweaknil();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,267 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.compiler;
 | 
			
		||||
 | 
			
		||||
import java.io.DataOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LocVars;
 | 
			
		||||
import org.luaj.vm2.Prototype;
 | 
			
		||||
import org.luaj.vm2.LuaString;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class DumpState {
 | 
			
		||||
 | 
			
		||||
	/** mark for precompiled code (`<esc>Lua') */
 | 
			
		||||
	public static final String LUA_SIGNATURE	= "\033Lua";
 | 
			
		||||
 | 
			
		||||
	/** for header of binary files -- this is Lua 5.1 */
 | 
			
		||||
	public static final int LUAC_VERSION		= 0x51;
 | 
			
		||||
 | 
			
		||||
	/** for header of binary files -- this is the official format */
 | 
			
		||||
	public static final int LUAC_FORMAT		= 0;
 | 
			
		||||
 | 
			
		||||
	/** size of header of binary files */
 | 
			
		||||
	public static final int LUAC_HEADERSIZE		= 12;
 | 
			
		||||
 | 
			
		||||
	/** expected lua header bytes */
 | 
			
		||||
	private static final byte[] LUAC_HEADER_SIGNATURE = { '\033', 'L', 'u', 'a' };
 | 
			
		||||
 | 
			
		||||
	/** set true to allow integer compilation */
 | 
			
		||||
	public static boolean ALLOW_INTEGER_CASTING = false;
 | 
			
		||||
	
 | 
			
		||||
	/** format corresponding to non-number-patched lua, all numbers are floats or doubles */
 | 
			
		||||
	public static final int NUMBER_FORMAT_FLOATS_OR_DOUBLES    = 0;
 | 
			
		||||
 | 
			
		||||
	/** format corresponding to non-number-patched lua, all numbers are ints */
 | 
			
		||||
	public static final int NUMBER_FORMAT_INTS_ONLY            = 1;
 | 
			
		||||
	
 | 
			
		||||
	/** format corresponding to number-patched lua, all numbers are 32-bit (4 byte) ints */
 | 
			
		||||
	public static final int NUMBER_FORMAT_NUM_PATCH_INT32      = 4;
 | 
			
		||||
	
 | 
			
		||||
	/** default number format */
 | 
			
		||||
	public static final int NUMBER_FORMAT_DEFAULT = NUMBER_FORMAT_FLOATS_OR_DOUBLES;
 | 
			
		||||
 | 
			
		||||
	// header fields
 | 
			
		||||
	private boolean IS_LITTLE_ENDIAN = false;
 | 
			
		||||
	private int NUMBER_FORMAT = NUMBER_FORMAT_DEFAULT;
 | 
			
		||||
	private int SIZEOF_LUA_NUMBER = 8;
 | 
			
		||||
	private static final int SIZEOF_INT = 4;
 | 
			
		||||
	private static final int SIZEOF_SIZET = 4;
 | 
			
		||||
	private static final int SIZEOF_INSTRUCTION = 4;
 | 
			
		||||
 | 
			
		||||
	DataOutputStream writer;
 | 
			
		||||
	boolean strip;
 | 
			
		||||
	int status;
 | 
			
		||||
 | 
			
		||||
	public DumpState(OutputStream w, boolean strip) {
 | 
			
		||||
		this.writer = new DataOutputStream( w );
 | 
			
		||||
		this.strip = strip;
 | 
			
		||||
		this.status = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void dumpBlock(final byte[] b, int size) throws IOException {
 | 
			
		||||
		writer.write(b, 0, size);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void dumpChar(int b) throws IOException {
 | 
			
		||||
		writer.write( b );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void dumpInt(int x) throws IOException {
 | 
			
		||||
		if ( IS_LITTLE_ENDIAN ) {
 | 
			
		||||
			writer.writeByte(x&0xff);
 | 
			
		||||
			writer.writeByte((x>>8)&0xff);
 | 
			
		||||
			writer.writeByte((x>>16)&0xff);
 | 
			
		||||
			writer.writeByte((x>>24)&0xff);
 | 
			
		||||
		} else {
 | 
			
		||||
			writer.writeInt(x);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	void dumpString(LuaString s) throws IOException {
 | 
			
		||||
		final int len = s.len().toint();
 | 
			
		||||
		dumpInt( len+1 );
 | 
			
		||||
		s.write( writer, 0, len );
 | 
			
		||||
		writer.write( 0 );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	void dumpDouble(double d) throws IOException {
 | 
			
		||||
		long l = Double.doubleToLongBits(d);
 | 
			
		||||
		if ( IS_LITTLE_ENDIAN ) {
 | 
			
		||||
			dumpInt( (int) l );
 | 
			
		||||
			dumpInt( (int) (l>>32) );
 | 
			
		||||
		} else {
 | 
			
		||||
			writer.writeLong(l);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void dumpCode( final Prototype f ) throws IOException {
 | 
			
		||||
		final int[] code = f.code;
 | 
			
		||||
		int n = code.length;
 | 
			
		||||
		dumpInt( n );
 | 
			
		||||
		for ( int i=0; i<n; i++ )
 | 
			
		||||
			dumpInt( code[i] );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	void dumpConstants(final Prototype f) throws IOException {
 | 
			
		||||
		final LuaValue[] k = f.k;
 | 
			
		||||
		int i, n = k.length;
 | 
			
		||||
		dumpInt(n);
 | 
			
		||||
		for (i = 0; i < n; i++) {
 | 
			
		||||
			final LuaValue o = k[i];
 | 
			
		||||
			switch ( o.type() ) {
 | 
			
		||||
			case LuaValue.TNIL:
 | 
			
		||||
				writer.write(LuaValue.TNIL);
 | 
			
		||||
				break;
 | 
			
		||||
			case LuaValue.TBOOLEAN:
 | 
			
		||||
				writer.write(LuaValue.TBOOLEAN);
 | 
			
		||||
				dumpChar(o.toboolean() ? 1 : 0);
 | 
			
		||||
				break;
 | 
			
		||||
			case LuaValue.TNUMBER:
 | 
			
		||||
				switch (NUMBER_FORMAT) {
 | 
			
		||||
				case NUMBER_FORMAT_FLOATS_OR_DOUBLES:
 | 
			
		||||
					writer.write(LuaValue.TNUMBER);
 | 
			
		||||
					dumpDouble(o.todouble());
 | 
			
		||||
					break;
 | 
			
		||||
				case NUMBER_FORMAT_INTS_ONLY:
 | 
			
		||||
					if ( ! ALLOW_INTEGER_CASTING && ! o.isint() )
 | 
			
		||||
						throw new java.lang.IllegalArgumentException("not an integer: "+o);
 | 
			
		||||
					writer.write(LuaValue.TNUMBER);
 | 
			
		||||
					dumpInt(o.toint());
 | 
			
		||||
					break;
 | 
			
		||||
				case NUMBER_FORMAT_NUM_PATCH_INT32:
 | 
			
		||||
					if ( o.isint() ) {
 | 
			
		||||
						writer.write(LuaValue.TINT);
 | 
			
		||||
						dumpInt(o.toint());
 | 
			
		||||
					} else {
 | 
			
		||||
						writer.write(LuaValue.TNUMBER);
 | 
			
		||||
						dumpDouble(o.todouble());
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					throw new IllegalArgumentException("number format not supported: "+NUMBER_FORMAT);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case LuaValue.TSTRING:
 | 
			
		||||
				writer.write(LuaValue.TSTRING);
 | 
			
		||||
				dumpString((LuaString)o);
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				throw new IllegalArgumentException("bad type for " + o);			
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		n = f.p.length;
 | 
			
		||||
		dumpInt(n);
 | 
			
		||||
		for (i = 0; i < n; i++)
 | 
			
		||||
			dumpFunction(f.p[i], f.source);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	void dumpDebug(final Prototype f) throws IOException {
 | 
			
		||||
		int i, n;
 | 
			
		||||
		n = (strip) ? 0 : f.lineinfo.length;
 | 
			
		||||
		dumpInt(n);
 | 
			
		||||
		for (i = 0; i < n; i++)
 | 
			
		||||
			dumpInt(f.lineinfo[i]);
 | 
			
		||||
		n = (strip) ? 0 : f.locvars.length;
 | 
			
		||||
		dumpInt(n);
 | 
			
		||||
		for (i = 0; i < n; i++) {
 | 
			
		||||
			LocVars lvi = f.locvars[i];
 | 
			
		||||
			dumpString(lvi.varname);
 | 
			
		||||
			dumpInt(lvi.startpc);
 | 
			
		||||
			dumpInt(lvi.endpc);
 | 
			
		||||
		}
 | 
			
		||||
		n = (strip) ? 0 : f.upvalues.length;
 | 
			
		||||
		dumpInt(n);
 | 
			
		||||
		for (i = 0; i < n; i++)
 | 
			
		||||
			dumpString(f.upvalues[i]);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	void dumpFunction(final Prototype f, final LuaString string) throws IOException {
 | 
			
		||||
		if ( f.source == null || f.source.equals(string) || strip )
 | 
			
		||||
			dumpInt(0);
 | 
			
		||||
		else
 | 
			
		||||
			dumpString(f.source);
 | 
			
		||||
		dumpInt(f.linedefined);
 | 
			
		||||
		dumpInt(f.lastlinedefined);
 | 
			
		||||
		dumpChar(f.nups);
 | 
			
		||||
		dumpChar(f.numparams);
 | 
			
		||||
		dumpChar(f.is_vararg);
 | 
			
		||||
		dumpChar(f.maxstacksize);
 | 
			
		||||
		dumpCode(f);
 | 
			
		||||
		dumpConstants(f);
 | 
			
		||||
		dumpDebug(f);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void dumpHeader() throws IOException {
 | 
			
		||||
		writer.write( LUAC_HEADER_SIGNATURE );
 | 
			
		||||
		writer.write( LUAC_VERSION );
 | 
			
		||||
		writer.write( LUAC_FORMAT );
 | 
			
		||||
		writer.write( IS_LITTLE_ENDIAN? 1: 0 );
 | 
			
		||||
		writer.write( SIZEOF_INT );
 | 
			
		||||
		writer.write( SIZEOF_SIZET );
 | 
			
		||||
		writer.write( SIZEOF_INSTRUCTION );
 | 
			
		||||
		writer.write( SIZEOF_LUA_NUMBER );
 | 
			
		||||
		writer.write( NUMBER_FORMAT );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	** dump Lua function as precompiled chunk
 | 
			
		||||
	*/
 | 
			
		||||
	public static int dump( Prototype f, OutputStream w, boolean strip ) throws IOException {
 | 
			
		||||
		DumpState D = new DumpState(w,strip);
 | 
			
		||||
		D.dumpHeader();
 | 
			
		||||
		D.dumpFunction(f,null);
 | 
			
		||||
		return D.status;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param f the function to dump
 | 
			
		||||
	 * @param w the output stream to dump to
 | 
			
		||||
	 * @param stripDebug true to strip debugging info, false otherwise
 | 
			
		||||
	 * @param numberFormat one of NUMBER_FORMAT_FLOATS_OR_DOUBLES, NUMBER_FORMAT_INTS_ONLY, NUMBER_FORMAT_NUM_PATCH_INT32
 | 
			
		||||
	 * @param littleendian true to use little endian for numbers, false for big endian
 | 
			
		||||
	 * @return 0 if dump succeeds
 | 
			
		||||
	 * @throws IOException
 | 
			
		||||
	 * @throws IllegalArgumentException if the number format it not supported
 | 
			
		||||
	 */
 | 
			
		||||
	public static int dump(Prototype f, OutputStream w, boolean stripDebug, int numberFormat, boolean littleendian) throws IOException {
 | 
			
		||||
		switch ( numberFormat ) {
 | 
			
		||||
		case NUMBER_FORMAT_FLOATS_OR_DOUBLES:
 | 
			
		||||
		case NUMBER_FORMAT_INTS_ONLY:
 | 
			
		||||
		case NUMBER_FORMAT_NUM_PATCH_INT32:
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			throw new IllegalArgumentException("number format not supported: "+numberFormat);
 | 
			
		||||
		}
 | 
			
		||||
		DumpState D = new DumpState(w,stripDebug);
 | 
			
		||||
		D.IS_LITTLE_ENDIAN = littleendian;
 | 
			
		||||
		D.NUMBER_FORMAT = numberFormat;
 | 
			
		||||
		D.SIZEOF_LUA_NUMBER = (numberFormat==NUMBER_FORMAT_INTS_ONLY? 4: 8);
 | 
			
		||||
		D.dumpHeader();
 | 
			
		||||
		D.dumpFunction(f,null);
 | 
			
		||||
		return D.status;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,37 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.compiler;
 | 
			
		||||
 | 
			
		||||
class InstructionPtr {
 | 
			
		||||
	final int[] code;
 | 
			
		||||
	final int idx;
 | 
			
		||||
	InstructionPtr(int[] code, int idx ) {
 | 
			
		||||
		this.code = code;
 | 
			
		||||
		this.idx = idx;
 | 
			
		||||
	}
 | 
			
		||||
	int get() {
 | 
			
		||||
		return code[idx];
 | 
			
		||||
	}
 | 
			
		||||
	void set(int value) {
 | 
			
		||||
		code[idx] = value;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.compiler;
 | 
			
		||||
 | 
			
		||||
public class IntPtr {
 | 
			
		||||
	int i;
 | 
			
		||||
	IntPtr() {
 | 
			
		||||
	}
 | 
			
		||||
	IntPtr(int value) {
 | 
			
		||||
		this.i = value;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,251 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.compiler;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.util.Hashtable;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LoadState;
 | 
			
		||||
import org.luaj.vm2.LocVars;
 | 
			
		||||
import org.luaj.vm2.Lua;
 | 
			
		||||
import org.luaj.vm2.LuaClosure;
 | 
			
		||||
import org.luaj.vm2.LuaError;
 | 
			
		||||
import org.luaj.vm2.LuaFunction;
 | 
			
		||||
import org.luaj.vm2.LuaString;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Prototype;
 | 
			
		||||
import org.luaj.vm2.LoadState.LuaCompiler;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compiler for Lua.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Compiles lua source files into lua bytecode within a {@link Prototype}, 
 | 
			
		||||
 * loads lua binary files directly into a{@link Prototype}, 
 | 
			
		||||
 * and optionaly instantiates a {@link LuaClosure} around the result 
 | 
			
		||||
 * using a user-supplied environment.  
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Implements the {@link LuaCompiler} interface for loading 
 | 
			
		||||
 * initialized chunks, which is an interface common to 
 | 
			
		||||
 * lua bytecode compiling and java bytecode compiling. 
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * Teh {@link LuaC} compiler is installed by default by both the 
 | 
			
		||||
 * {@link JsePlatform} and {@link JmePlatform} classes, 
 | 
			
		||||
 * so in the following example, the default {@link LuaC} compiler 
 | 
			
		||||
 * will be used:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LuaValue _G = JsePlatform.standardGlobals();
 | 
			
		||||
 * LoadState.load( new ByteArrayInputStream("print 'hello'".getBytes()), "main.lua", _G ).call();
 | 
			
		||||
 * } </pre>
 | 
			
		||||
 * @see LuaCompiler
 | 
			
		||||
 * @see LuaJC
 | 
			
		||||
 * @see JsePlatform
 | 
			
		||||
 * @see JmePlatform
 | 
			
		||||
 * @see BaseLib
 | 
			
		||||
 * @see LuaValue
 | 
			
		||||
 * @see LuaCompiler
 | 
			
		||||
 * @see Prototype
 | 
			
		||||
 */
 | 
			
		||||
public class LuaC extends Lua implements LuaCompiler {
 | 
			
		||||
 | 
			
		||||
	public static final LuaC instance = new LuaC();
 | 
			
		||||
	
 | 
			
		||||
	/** Install the compiler so that LoadState will first 
 | 
			
		||||
	 * try to use it when handed bytes that are 
 | 
			
		||||
	 * not already a compiled lua chunk.
 | 
			
		||||
	 */
 | 
			
		||||
	public static void install() {
 | 
			
		||||
		org.luaj.vm2.LoadState.compiler = instance;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	protected static void _assert(boolean b) {		
 | 
			
		||||
		if (!b)
 | 
			
		||||
			throw new LuaError("compiler assert failed");
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static final int MAXSTACK = 250;
 | 
			
		||||
	static final int LUAI_MAXUPVALUES = 60;
 | 
			
		||||
	static final int LUAI_MAXVARS = 200;
 | 
			
		||||
	static final int NO_REG		 = MAXARG_A;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/* OpMode - basic instruction format */
 | 
			
		||||
	static final int 
 | 
			
		||||
		iABC = 0,
 | 
			
		||||
		iABx = 1,
 | 
			
		||||
		iAsBx = 2;
 | 
			
		||||
 | 
			
		||||
	/* OpArgMask */
 | 
			
		||||
	static final int 
 | 
			
		||||
	  OpArgN = 0,  /* argument is not used */
 | 
			
		||||
	  OpArgU = 1,  /* argument is used */
 | 
			
		||||
	  OpArgR = 2,  /* argument is a register or a jump offset */
 | 
			
		||||
	  OpArgK = 3;   /* argument is a constant or register/constant */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	static void SET_OPCODE(InstructionPtr i,int o) {
 | 
			
		||||
		i.set( ( i.get() & (MASK_NOT_OP)) | ((o << POS_OP) & MASK_OP) );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	static void SETARG_A(InstructionPtr i,int u) {
 | 
			
		||||
		i.set( ( i.get() & (MASK_NOT_A)) | ((u << POS_A) & MASK_A) );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static void SETARG_B(InstructionPtr i,int u) {
 | 
			
		||||
		i.set( ( i.get() & (MASK_NOT_B)) | ((u << POS_B) & MASK_B) );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static void SETARG_C(InstructionPtr i,int u) {
 | 
			
		||||
		i.set( ( i.get() & (MASK_NOT_C)) | ((u << POS_C) & MASK_C) );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	static void SETARG_Bx(InstructionPtr i,int u) {
 | 
			
		||||
		i.set( ( i.get() & (MASK_NOT_Bx)) | ((u << POS_Bx) & MASK_Bx) );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	static void SETARG_sBx(InstructionPtr i,int u) {
 | 
			
		||||
		SETARG_Bx( i, u + MAXARG_sBx );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static int CREATE_ABC(int o, int a, int b, int c) {
 | 
			
		||||
		return ((o << POS_OP) & MASK_OP) |
 | 
			
		||||
				((a << POS_A) & MASK_A) |
 | 
			
		||||
				((b << POS_B) & MASK_B) |
 | 
			
		||||
				((c << POS_C) & MASK_C) ;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	static int CREATE_ABx(int o, int a, int bc) {
 | 
			
		||||
		return ((o << POS_OP) & MASK_OP) |
 | 
			
		||||
				((a << POS_A) & MASK_A) |
 | 
			
		||||
				((bc << POS_Bx) & MASK_Bx) ;
 | 
			
		||||
 	}
 | 
			
		||||
 | 
			
		||||
	// vector reallocation
 | 
			
		||||
	
 | 
			
		||||
	static LuaValue[] realloc(LuaValue[] v, int n) {
 | 
			
		||||
		LuaValue[] a = new LuaValue[n];
 | 
			
		||||
		if ( v != null )
 | 
			
		||||
			System.arraycopy(v, 0, a, 0, Math.min(v.length,n));
 | 
			
		||||
		return a;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static Prototype[] realloc(Prototype[] v, int n) {
 | 
			
		||||
		Prototype[] a = new Prototype[n];
 | 
			
		||||
		if ( v != null )
 | 
			
		||||
			System.arraycopy(v, 0, a, 0, Math.min(v.length,n));
 | 
			
		||||
		return a;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static LuaString[] realloc(LuaString[] v, int n) {
 | 
			
		||||
		LuaString[] a = new LuaString[n];
 | 
			
		||||
		if ( v != null )
 | 
			
		||||
			System.arraycopy(v, 0, a, 0, Math.min(v.length,n));
 | 
			
		||||
		return a;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static LocVars[] realloc(LocVars[] v, int n) {
 | 
			
		||||
		LocVars[] a = new LocVars[n];
 | 
			
		||||
		if ( v != null )
 | 
			
		||||
			System.arraycopy(v, 0, a, 0, Math.min(v.length,n));
 | 
			
		||||
		return a;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static int[] realloc(int[] v, int n) {
 | 
			
		||||
		int[] a = new int[n];
 | 
			
		||||
		if ( v != null )
 | 
			
		||||
			System.arraycopy(v, 0, a, 0, Math.min(v.length,n));
 | 
			
		||||
		return a;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static byte[] realloc(byte[] v, int n) {
 | 
			
		||||
		byte[] a = new byte[n];
 | 
			
		||||
		if ( v != null )
 | 
			
		||||
			System.arraycopy(v, 0, a, 0, Math.min(v.length,n));
 | 
			
		||||
		return a;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int nCcalls;
 | 
			
		||||
	Hashtable strings;
 | 
			
		||||
 | 
			
		||||
	protected LuaC() {}
 | 
			
		||||
	
 | 
			
		||||
	private LuaC(Hashtable strings) {
 | 
			
		||||
		 this.strings = strings;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Load into a Closure or LuaFunction, with the supplied initial environment */
 | 
			
		||||
	public LuaFunction load(InputStream stream, String name, LuaValue env) throws IOException {
 | 
			
		||||
		Prototype p = compile( stream, name );
 | 
			
		||||
		return new LuaClosure( p, env );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Compile a prototype or load as a binary chunk */
 | 
			
		||||
	public static Prototype compile(InputStream stream, String name) throws IOException {
 | 
			
		||||
		int firstByte = stream.read();
 | 
			
		||||
		return ( firstByte == '\033' )?
 | 
			
		||||
			LoadState.loadBinaryChunk(firstByte, stream, name):
 | 
			
		||||
			(new LuaC(new Hashtable())).luaY_parser(firstByte, stream, name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Parse the input */
 | 
			
		||||
	private Prototype luaY_parser(int firstByte, InputStream z, String name) {
 | 
			
		||||
		LexState lexstate = new LexState(this, z);
 | 
			
		||||
		FuncState funcstate = new FuncState();
 | 
			
		||||
		// lexstate.buff = buff;
 | 
			
		||||
		lexstate.setinput( this, firstByte, z, (LuaString) LuaValue.valueOf(name) );
 | 
			
		||||
		lexstate.open_func(funcstate);
 | 
			
		||||
		/* main func. is always vararg */
 | 
			
		||||
		funcstate.f.is_vararg = LuaC.VARARG_ISVARARG;
 | 
			
		||||
		funcstate.f.source = (LuaString) LuaValue.valueOf(name);
 | 
			
		||||
		lexstate.next(); /* read first token */
 | 
			
		||||
		lexstate.chunk();
 | 
			
		||||
		lexstate.check(LexState.TK_EOS);
 | 
			
		||||
		lexstate.close_func();
 | 
			
		||||
		LuaC._assert (funcstate.prev == null);
 | 
			
		||||
		LuaC._assert (funcstate.f.nups == 0);
 | 
			
		||||
		LuaC._assert (lexstate.fs == null);
 | 
			
		||||
		return funcstate.f;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// look up and keep at most one copy of each string
 | 
			
		||||
	public LuaString newTString(byte[] bytes, int offset, int len) {
 | 
			
		||||
		LuaString tmp = LuaString.valueOf(bytes, offset, len);
 | 
			
		||||
		LuaString v = (LuaString) strings.get(tmp);
 | 
			
		||||
		if ( v == null ) {
 | 
			
		||||
			// must copy bytes, since bytes could be from reusable buffer
 | 
			
		||||
			byte[] copy = new byte[len];
 | 
			
		||||
			System.arraycopy(bytes, offset, copy, 0, len);
 | 
			
		||||
			v = LuaString.valueOf(copy);
 | 
			
		||||
			strings.put(v, v);
 | 
			
		||||
		}
 | 
			
		||||
		return v;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String pushfstring(String string) {
 | 
			
		||||
		return string;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaFunction load(Prototype p, String filename, LuaValue env) {
 | 
			
		||||
		return new LuaClosure( p, env );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,430 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.PrintStream;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LoadState;
 | 
			
		||||
import org.luaj.vm2.Lua;
 | 
			
		||||
import org.luaj.vm2.LuaError;
 | 
			
		||||
import org.luaj.vm2.LuaString;
 | 
			
		||||
import org.luaj.vm2.LuaTable;
 | 
			
		||||
import org.luaj.vm2.LuaThread;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Subclass of {@link LibFunction} which implements the lua basic library functions. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This contains all library functions listed as "basic functions" in the lua documentation for JME. 
 | 
			
		||||
 * The functions dofile and loadfile use the 
 | 
			
		||||
 * {@link #FINDER} instance to find resource files.
 | 
			
		||||
 * Since JME has no file system by default, {@link BaseLib} implements 
 | 
			
		||||
 * {@link ResourceFinder} using {@link Class#getResource(String)}, 
 | 
			
		||||
 * which is the closest equivalent on JME.     
 | 
			
		||||
 * The default loader chain in {@link PackageLib} will use these as well.
 | 
			
		||||
 * <p>  
 | 
			
		||||
 * To use basic library functions that include a {@link ResourceFinder} based on 
 | 
			
		||||
 * directory lookup, use {@link JseBaseLib} instead. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Typically, this library is included as part of a call to either 
 | 
			
		||||
 * {@link JmePlatform#standardGlobals()}
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To instantiate and use it directly, 
 | 
			
		||||
 * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LuaTable _G = new LuaTable();
 | 
			
		||||
 * LuaThread.setGlobals(_G);
 | 
			
		||||
 * _G.load(new BaseLib());
 | 
			
		||||
 * _G.get("print").call(LuaValue.valueOf("hello, world"));
 | 
			
		||||
 * } </pre>
 | 
			
		||||
 * Doing so will ensure the library is properly initialized 
 | 
			
		||||
 * and loaded into the globals table. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This is a direct port of the corresponding library in C.
 | 
			
		||||
 * @see JseBaseLib
 | 
			
		||||
 * @see ResourceFinder
 | 
			
		||||
 * @see #FINDER
 | 
			
		||||
 * @see LibFunction
 | 
			
		||||
 * @see JsePlatform
 | 
			
		||||
 * @see JmePlatform
 | 
			
		||||
 * @see <a href="http://www.lua.org/manual/5.1/manual.html#5.1">http://www.lua.org/manual/5.1/manual.html#5.1</a>
 | 
			
		||||
 */
 | 
			
		||||
public class BaseLib extends OneArgFunction implements ResourceFinder {
 | 
			
		||||
	
 | 
			
		||||
	public static BaseLib instance;
 | 
			
		||||
	
 | 
			
		||||
	public InputStream STDIN  = null;
 | 
			
		||||
	public PrintStream STDOUT = System.out;
 | 
			
		||||
	public PrintStream STDERR = System.err;
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Singleton file opener for this Java ClassLoader realm.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * Unless set or changed elsewhere, will be set by the BaseLib that is created.
 | 
			
		||||
	 */
 | 
			
		||||
	public static ResourceFinder FINDER;
 | 
			
		||||
	
 | 
			
		||||
	private LuaValue next;
 | 
			
		||||
	private LuaValue inext;
 | 
			
		||||
	
 | 
			
		||||
	private static final String[] LIB2_KEYS = {
 | 
			
		||||
		"collectgarbage", // ( opt [,arg] ) -> value
 | 
			
		||||
		"error", // ( message [,level] ) -> ERR
 | 
			
		||||
		"setfenv", // (f, table) -> void
 | 
			
		||||
	};
 | 
			
		||||
	private static final String[] LIBV_KEYS = {
 | 
			
		||||
		"assert", // ( v [,message] ) -> v, message | ERR
 | 
			
		||||
		"dofile", // ( filename ) -> result1, ...
 | 
			
		||||
		"getfenv", // ( [f] ) -> env
 | 
			
		||||
		"getmetatable", // ( object ) -> table 
 | 
			
		||||
		"load", // ( func [,chunkname] ) -> chunk | nil, msg
 | 
			
		||||
		"loadfile", // ( [filename] ) -> chunk | nil, msg
 | 
			
		||||
		"loadstring", // ( string [,chunkname] ) -> chunk | nil, msg
 | 
			
		||||
		"pcall", // (f, arg1, ...) -> status, result1, ...
 | 
			
		||||
		"xpcall", // (f, err) -> result1, ...
 | 
			
		||||
		"print", // (...) -> void
 | 
			
		||||
		"select", // (f, ...) -> value1, ...
 | 
			
		||||
		"unpack", // (list [,i [,j]]) -> result1, ...
 | 
			
		||||
		"type",  // (v) -> value
 | 
			
		||||
		"rawequal", // (v1, v2) -> boolean
 | 
			
		||||
		"rawget", // (table, index) -> value
 | 
			
		||||
		"rawset", // (table, index, value) -> table
 | 
			
		||||
		"setmetatable", // (table, metatable) -> table
 | 
			
		||||
		"tostring", // (e) -> value
 | 
			
		||||
		"tonumber", // (e [,base]) -> value
 | 
			
		||||
		"pairs", // "pairs" (t) -> iter-func, t, nil
 | 
			
		||||
		"ipairs", // "ipairs", // (t) -> iter-func, t, 0
 | 
			
		||||
		"next", // "next"  ( table, [index] ) -> next-index, next-value
 | 
			
		||||
		"__inext", // "inext" ( table, [int-index] ) -> next-index, next-value
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Construct a base libarary instance.
 | 
			
		||||
	 */
 | 
			
		||||
	public BaseLib() {
 | 
			
		||||
		instance = this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue call(LuaValue arg) {
 | 
			
		||||
		env.set( "_G", env );
 | 
			
		||||
		env.set( "_VERSION", Lua._VERSION );
 | 
			
		||||
		bind( env, BaseLib2.class, LIB2_KEYS );
 | 
			
		||||
		bind( env, BaseLibV.class, LIBV_KEYS ); 
 | 
			
		||||
		
 | 
			
		||||
		// remember next, and inext for use in pairs and ipairs
 | 
			
		||||
		next = env.get("next");
 | 
			
		||||
		inext = env.get("__inext");
 | 
			
		||||
		
 | 
			
		||||
		// inject base lib int vararg instances
 | 
			
		||||
		for ( int i=0; i<LIBV_KEYS.length; i++ ) 
 | 
			
		||||
			((BaseLibV) env.get(LIBV_KEYS[i])).baselib = this;
 | 
			
		||||
		
 | 
			
		||||
		// set the default resource finder if not set already
 | 
			
		||||
		if ( FINDER == null )
 | 
			
		||||
			FINDER = this;
 | 
			
		||||
		return env;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** ResourceFinder implementation 
 | 
			
		||||
	 * 
 | 
			
		||||
	 * Tries to open the file as a resource, which can work for . 
 | 
			
		||||
	 */
 | 
			
		||||
	public InputStream findResource(String filename) {
 | 
			
		||||
		Class c = getClass();
 | 
			
		||||
		return c.getResourceAsStream(filename.startsWith("/")? filename: "/"+filename);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static final class BaseLib2 extends TwoArgFunction {
 | 
			
		||||
		public LuaValue call(LuaValue arg1, LuaValue arg2) {
 | 
			
		||||
			switch ( opcode ) {
 | 
			
		||||
			case 0: // "collectgarbage", // ( opt [,arg] ) -> value
 | 
			
		||||
				String s = arg1.checkjstring();
 | 
			
		||||
				int result = 0;
 | 
			
		||||
				if ( "collect".equals(s) ) {
 | 
			
		||||
					System.gc();
 | 
			
		||||
					return ZERO;
 | 
			
		||||
				} else if ( "count".equals(s) ) {
 | 
			
		||||
					Runtime rt = Runtime.getRuntime();
 | 
			
		||||
					long used = rt.totalMemory() - rt.freeMemory();
 | 
			
		||||
					return valueOf(used/1024.);
 | 
			
		||||
				} else if ( "step".equals(s) ) {
 | 
			
		||||
					System.gc();
 | 
			
		||||
					return LuaValue.TRUE;
 | 
			
		||||
				} else {
 | 
			
		||||
					this.argerror(1, "gc op");
 | 
			
		||||
				}
 | 
			
		||||
				return NIL;
 | 
			
		||||
			case 1: // "error", // ( message [,level] ) -> ERR
 | 
			
		||||
				throw new LuaError( arg1.isnil()? null: arg1.tojstring(), arg2.optint(1) );
 | 
			
		||||
			case 2: { // "setfenv", // (f, table) -> void
 | 
			
		||||
				LuaTable t = arg2.checktable();
 | 
			
		||||
				LuaValue f = getfenvobj(arg1);
 | 
			
		||||
				if ( ! f.isthread() && ! f.isclosure()  )
 | 
			
		||||
					error("'setfenv' cannot change environment of given object");
 | 
			
		||||
			    f.setfenv(t);
 | 
			
		||||
			    return f.isthread()? NONE: f;
 | 
			
		||||
			}
 | 
			
		||||
			}
 | 
			
		||||
			return NIL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private static LuaValue getfenvobj(LuaValue arg) {
 | 
			
		||||
		if ( arg.isfunction() )
 | 
			
		||||
			return arg;
 | 
			
		||||
		int level = arg.optint(1);
 | 
			
		||||
	    arg.argcheck(level>=0, 1, "level must be non-negative");
 | 
			
		||||
		if ( level == 0 )
 | 
			
		||||
			return LuaThread.getRunning();
 | 
			
		||||
		LuaValue f = LuaThread.getCallstackFunction(level);
 | 
			
		||||
	    arg.argcheck(f != null, 1, "invalid level");
 | 
			
		||||
	    return f;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static final class BaseLibV extends VarArgFunction {
 | 
			
		||||
		public BaseLib baselib;
 | 
			
		||||
		public Varargs invoke(Varargs args) {
 | 
			
		||||
			switch ( opcode ) {
 | 
			
		||||
			case 0: // "assert", // ( v [,message] ) -> v, message | ERR
 | 
			
		||||
				if ( !args.arg1().toboolean() ) 
 | 
			
		||||
					error( args.narg()>1? args.optjstring(2,"assertion failed!"): "assertion failed!" );
 | 
			
		||||
				return args;
 | 
			
		||||
			case 1: // "dofile", // ( filename ) -> result1, ...
 | 
			
		||||
			{
 | 
			
		||||
				Varargs v = args.isnil(1)? 
 | 
			
		||||
						BaseLib.loadStream( baselib.STDIN, "=stdin" ):
 | 
			
		||||
						BaseLib.loadFile( args.checkjstring(1) );
 | 
			
		||||
				return v.isnil(1)? error(v.tojstring(2)): v.arg1().invoke();
 | 
			
		||||
			}
 | 
			
		||||
			case 2: // "getfenv", // ( [f] ) -> env
 | 
			
		||||
			{
 | 
			
		||||
				LuaValue f = getfenvobj(args.arg1());
 | 
			
		||||
			    LuaValue e = f.getfenv();
 | 
			
		||||
				return e!=null? e: NIL;
 | 
			
		||||
			}
 | 
			
		||||
			case 3: // "getmetatable", // ( object ) -> table
 | 
			
		||||
			{
 | 
			
		||||
				LuaValue mt = args.checkvalue(1).getmetatable();
 | 
			
		||||
				return mt!=null? mt.rawget(METATABLE).optvalue(mt): NIL;
 | 
			
		||||
			}
 | 
			
		||||
			case 4: // "load", // ( func [,chunkname] ) -> chunk | nil, msg
 | 
			
		||||
			{
 | 
			
		||||
				LuaValue func = args.checkfunction(1);
 | 
			
		||||
				String chunkname = args.optjstring(2, "function");
 | 
			
		||||
				return BaseLib.loadStream(new StringInputStream(func), chunkname);
 | 
			
		||||
			}
 | 
			
		||||
			case 5: // "loadfile", // ( [filename] ) -> chunk | nil, msg
 | 
			
		||||
			{
 | 
			
		||||
				return args.isnil(1)? 
 | 
			
		||||
					BaseLib.loadStream( baselib.STDIN, "stdin" ):
 | 
			
		||||
					BaseLib.loadFile( args.checkjstring(1) );
 | 
			
		||||
			}
 | 
			
		||||
			case 6: // "loadstring", // ( string [,chunkname] ) -> chunk | nil, msg
 | 
			
		||||
			{
 | 
			
		||||
				LuaString script = args.checkstring(1);
 | 
			
		||||
				String chunkname = args.optjstring(2, "string");
 | 
			
		||||
				return BaseLib.loadStream(script.toInputStream(),chunkname);
 | 
			
		||||
			}
 | 
			
		||||
			case 7: // "pcall", // (f, arg1, ...) -> status, result1, ...
 | 
			
		||||
			{
 | 
			
		||||
				LuaValue func = args.checkvalue(1);
 | 
			
		||||
				LuaThread.CallStack cs = LuaThread.onCall(this);
 | 
			
		||||
				try {
 | 
			
		||||
					return pcall(func,args.subargs(2),null);
 | 
			
		||||
				} finally {
 | 
			
		||||
					cs.onReturn();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			case 8: // "xpcall", // (f, err) -> result1, ...				
 | 
			
		||||
			{
 | 
			
		||||
				LuaThread.CallStack cs = LuaThread.onCall(this);
 | 
			
		||||
				try {
 | 
			
		||||
					return pcall(args.arg1(),NONE,args.checkvalue(2));
 | 
			
		||||
				} finally {
 | 
			
		||||
					cs.onReturn();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			case 9: // "print", // (...) -> void
 | 
			
		||||
			{
 | 
			
		||||
				LuaValue tostring = LuaThread.getGlobals().get("tostring"); 
 | 
			
		||||
				for ( int i=1, n=args.narg(); i<=n; i++ ) {
 | 
			
		||||
					if ( i>1 ) baselib.STDOUT.write( '\t' );
 | 
			
		||||
					LuaString s = tostring.call( args.arg(i) ).strvalue();
 | 
			
		||||
					int z = s.indexOf((byte)0, 0);
 | 
			
		||||
					baselib.STDOUT.write( s.m_bytes, s.m_offset, z>=0? z: s.m_length );
 | 
			
		||||
				}
 | 
			
		||||
				baselib.STDOUT.println();
 | 
			
		||||
				return NONE;
 | 
			
		||||
			}
 | 
			
		||||
			case 10: // "select", // (f, ...) -> value1, ...
 | 
			
		||||
			{
 | 
			
		||||
				int n = args.narg()-1; 				
 | 
			
		||||
				if ( args.arg1().equals(valueOf("#")) )
 | 
			
		||||
					return valueOf(n);
 | 
			
		||||
				int i = args.checkint(1);
 | 
			
		||||
				if ( i == 0 || i < -n )
 | 
			
		||||
					argerror(1,"index out of range");
 | 
			
		||||
				return args.subargs(i<0? n+i+2: i+1);
 | 
			
		||||
			}
 | 
			
		||||
			case 11: // "unpack", // (list [,i [,j]]) -> result1, ...
 | 
			
		||||
			{
 | 
			
		||||
				int na = args.narg();
 | 
			
		||||
				LuaTable t = args.checktable(1);
 | 
			
		||||
				int n = t.length();
 | 
			
		||||
				int i = na>=2? args.checkint(2): 1;
 | 
			
		||||
				int j = na>=3? args.checkint(3): n;
 | 
			
		||||
				n = j-i+1;
 | 
			
		||||
				if ( n<0 ) return NONE;
 | 
			
		||||
				if ( n==1 ) return t.get(i);
 | 
			
		||||
				if ( n==2 ) return varargsOf(t.get(i),t.get(j));
 | 
			
		||||
				LuaValue[] v = new LuaValue[n];
 | 
			
		||||
				for ( int k=0; k<n; k++ )
 | 
			
		||||
					v[k] = t.get(i+k);
 | 
			
		||||
				return varargsOf(v);
 | 
			
		||||
			}
 | 
			
		||||
			case 12: // "type",  // (v) -> value
 | 
			
		||||
				return valueOf(args.checkvalue(1).typename());
 | 
			
		||||
			case 13: // "rawequal", // (v1, v2) -> boolean
 | 
			
		||||
				return valueOf(args.checkvalue(1) == args.checkvalue(2));
 | 
			
		||||
			case 14: // "rawget", // (table, index) -> value
 | 
			
		||||
				return args.checktable(1).rawget(args.checkvalue(2));
 | 
			
		||||
			case 15: { // "rawset", // (table, index, value) -> table
 | 
			
		||||
				LuaTable t = args.checktable(1);
 | 
			
		||||
				t.rawset(args.checknotnil(2), args.checkvalue(3));
 | 
			
		||||
				return t;
 | 
			
		||||
			}
 | 
			
		||||
			case 16: { // "setmetatable", // (table, metatable) -> table
 | 
			
		||||
				final LuaValue t = args.arg1();
 | 
			
		||||
				final LuaValue mt0 = t.getmetatable();
 | 
			
		||||
				if ( mt0!=null && !mt0.rawget(METATABLE).isnil() )
 | 
			
		||||
					error("cannot change a protected metatable");
 | 
			
		||||
				final LuaValue mt = args.checkvalue(2);
 | 
			
		||||
				return t.setmetatable(mt.isnil()? null: mt.checktable());
 | 
			
		||||
			}
 | 
			
		||||
			case 17: { // "tostring", // (e) -> value
 | 
			
		||||
				LuaValue arg = args.checkvalue(1);
 | 
			
		||||
				LuaValue h = arg.metatag(TOSTRING);
 | 
			
		||||
				if ( ! h.isnil() ) 
 | 
			
		||||
					return h.call(arg);
 | 
			
		||||
				LuaValue v = arg.tostring();
 | 
			
		||||
				if ( ! v.isnil() ) 
 | 
			
		||||
					return v;
 | 
			
		||||
				return valueOf(arg.tojstring());
 | 
			
		||||
			}
 | 
			
		||||
			case 18: { // "tonumber", // (e [,base]) -> value
 | 
			
		||||
				LuaValue arg1 = args.checkvalue(1);
 | 
			
		||||
				final int base = args.optint(2,10);
 | 
			
		||||
				if (base == 10) {  /* standard conversion */
 | 
			
		||||
					return arg1.tonumber();
 | 
			
		||||
				} else {
 | 
			
		||||
					if ( base < 2 || base > 36 )
 | 
			
		||||
						argerror(2, "base out of range");
 | 
			
		||||
					return arg1.checkstring().tonumber(base);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			case 19: // "pairs" (t) -> iter-func, t, nil
 | 
			
		||||
				return varargsOf( baselib.next, args.checktable(1), NIL );
 | 
			
		||||
			case 20: // "ipairs", // (t) -> iter-func, t, 0
 | 
			
		||||
				return varargsOf( baselib.inext, args.checktable(1), ZERO );
 | 
			
		||||
			case 21: // "next"  ( table, [index] ) -> next-index, next-value
 | 
			
		||||
				return args.checktable(1).next(args.arg(2));
 | 
			
		||||
			case 22: // "inext" ( table, [int-index] ) -> next-index, next-value
 | 
			
		||||
				return args.checktable(1).inext(args.arg(2));
 | 
			
		||||
			}
 | 
			
		||||
			return NONE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Varargs pcall(LuaValue func, Varargs args, LuaValue errfunc) {
 | 
			
		||||
		LuaValue olderr = LuaThread.setErrorFunc(errfunc);
 | 
			
		||||
		try {
 | 
			
		||||
			Varargs result =  varargsOf(LuaValue.TRUE, func.invoke(args));
 | 
			
		||||
			LuaThread.setErrorFunc(olderr);
 | 
			
		||||
			return result;
 | 
			
		||||
		} catch ( LuaError le ) {
 | 
			
		||||
			LuaThread.setErrorFunc(olderr);
 | 
			
		||||
			String m = le.getMessage();
 | 
			
		||||
			return varargsOf(FALSE, m!=null? valueOf(m): NIL);
 | 
			
		||||
		} catch ( Exception e ) {
 | 
			
		||||
			LuaThread.setErrorFunc(olderr);
 | 
			
		||||
			String m = e.getMessage();
 | 
			
		||||
			return varargsOf(FALSE, valueOf(m!=null? m: e.toString()));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Load from a named file, returning the chunk or nil,error of can't load
 | 
			
		||||
	 * @return Varargs containing chunk, or NIL,error-text on error
 | 
			
		||||
	 */
 | 
			
		||||
	public static Varargs loadFile(String filename) {
 | 
			
		||||
		InputStream is = FINDER.findResource(filename);
 | 
			
		||||
		if ( is == null )
 | 
			
		||||
			return varargsOf(NIL, valueOf("cannot open "+filename+": No such file or directory"));
 | 
			
		||||
		try {
 | 
			
		||||
			return loadStream(is, "@"+filename);
 | 
			
		||||
		} finally {
 | 
			
		||||
			try {
 | 
			
		||||
				is.close();
 | 
			
		||||
			} catch ( Exception e ) {
 | 
			
		||||
				e.printStackTrace();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Varargs loadStream(InputStream is, String chunkname) {
 | 
			
		||||
		try {
 | 
			
		||||
			if ( is == null )
 | 
			
		||||
				return varargsOf(NIL, valueOf("not found: "+chunkname));
 | 
			
		||||
			return LoadState.load(is, chunkname, LuaThread.getGlobals());
 | 
			
		||||
		} catch (Exception e) {
 | 
			
		||||
			return varargsOf(NIL, valueOf(e.getMessage()));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	private static class StringInputStream extends InputStream {
 | 
			
		||||
		final LuaValue func;
 | 
			
		||||
		byte[] bytes; 
 | 
			
		||||
		int offset, remaining = 0;
 | 
			
		||||
		StringInputStream(LuaValue func) {
 | 
			
		||||
			this.func = func;
 | 
			
		||||
		}
 | 
			
		||||
		public int read() throws IOException {
 | 
			
		||||
			if ( remaining <= 0 ) {
 | 
			
		||||
				LuaValue s = func.call();
 | 
			
		||||
				if ( s.isnil() )
 | 
			
		||||
					return -1;
 | 
			
		||||
				LuaString ls = s.strvalue();
 | 
			
		||||
				bytes = ls.m_bytes;
 | 
			
		||||
				offset = ls.m_offset;
 | 
			
		||||
				remaining = ls.m_length;
 | 
			
		||||
				if (remaining <= 0)
 | 
			
		||||
					return -1;
 | 
			
		||||
			}
 | 
			
		||||
			--remaining;
 | 
			
		||||
			return bytes[offset++];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,181 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Copyright (c) 2012 Luaj.org. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaInteger;
 | 
			
		||||
import org.luaj.vm2.LuaTable;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Subclass of LibFunction that implements the Lua standard {@code bit32} library.
 | 
			
		||||
 */
 | 
			
		||||
public class Bit32Lib extends ZeroArgFunction
 | 
			
		||||
{
 | 
			
		||||
    public LuaValue call( )
 | 
			
		||||
    {
 | 
			
		||||
        LuaTable t = new LuaTable();
 | 
			
		||||
        bind( t, Bit32LibV.class, new String[] {
 | 
			
		||||
            "band", "bnot", "bor", "btest", "bxor", "extract", "replace"
 | 
			
		||||
        } );
 | 
			
		||||
        bind( t, Bit32Lib2.class, new String[] {
 | 
			
		||||
            "arshift", "lrotate", "lshift", "rrotate", "rshift"
 | 
			
		||||
        } );
 | 
			
		||||
        env.set( "bit32", t );
 | 
			
		||||
        return t;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final class Bit32LibV extends VarArgFunction
 | 
			
		||||
    {
 | 
			
		||||
        public Varargs invoke( Varargs args )
 | 
			
		||||
        {
 | 
			
		||||
            switch( opcode )
 | 
			
		||||
            {
 | 
			
		||||
                case 0: // band
 | 
			
		||||
                {
 | 
			
		||||
                    int result = -1;
 | 
			
		||||
                    for( int i = 1; i <= args.narg(); i++ )
 | 
			
		||||
                    {
 | 
			
		||||
                        result &= args.checkint( i );
 | 
			
		||||
                    }
 | 
			
		||||
                    return bitsToValue( result );
 | 
			
		||||
                }
 | 
			
		||||
                case 1: // bnot
 | 
			
		||||
                    return bitsToValue( ~args.checkint( 1 ) );
 | 
			
		||||
                case 2: // bot
 | 
			
		||||
                {
 | 
			
		||||
                    int result = 0;
 | 
			
		||||
                    for( int i = 1; i <= args.narg(); i++ )
 | 
			
		||||
                    {
 | 
			
		||||
                        result |= args.checkint( i );
 | 
			
		||||
                    }
 | 
			
		||||
                    return bitsToValue( result );
 | 
			
		||||
                }
 | 
			
		||||
                case 3: // btest
 | 
			
		||||
                {
 | 
			
		||||
                    int bits = -1;
 | 
			
		||||
                    for( int i = 1; i <= args.narg(); i++ )
 | 
			
		||||
                    {
 | 
			
		||||
                        bits &= args.checkint( i );
 | 
			
		||||
                    }
 | 
			
		||||
                    return valueOf( bits != 0 );
 | 
			
		||||
                }
 | 
			
		||||
                case 4: // bxor
 | 
			
		||||
                {
 | 
			
		||||
                    int result = 0;
 | 
			
		||||
                    for( int i = 1; i <= args.narg(); i++ )
 | 
			
		||||
                    {
 | 
			
		||||
                        result ^= args.checkint( i );
 | 
			
		||||
                    }
 | 
			
		||||
                    return bitsToValue( result );
 | 
			
		||||
                }
 | 
			
		||||
                case 5: // extract
 | 
			
		||||
                {
 | 
			
		||||
                    int field = args.checkint( 2 );
 | 
			
		||||
                    int width = args.optint( 3, 1 );
 | 
			
		||||
 | 
			
		||||
                    if( field < 0 ) argerror( 2, "field cannot be negative" );
 | 
			
		||||
                    if( width <= 0 ) argerror( 3, "width must be postive" );
 | 
			
		||||
                    if( field + width > 32 ) error( "trying to access non-existent bits" );
 | 
			
		||||
 | 
			
		||||
                    return bitsToValue( (args.checkint( 1 ) >>> field) & (-1 >>> (32 - width)) );
 | 
			
		||||
                }
 | 
			
		||||
                case 6: // replace
 | 
			
		||||
                {
 | 
			
		||||
                    int n = args.checkint( 1 );
 | 
			
		||||
                    int v = args.checkint( 2 );
 | 
			
		||||
                    int field = args.checkint( 3 );
 | 
			
		||||
                    int width = args.optint( 4, 1 );
 | 
			
		||||
 | 
			
		||||
                    if( field < 0 ) argerror( 3, "field cannot be negative" );
 | 
			
		||||
                    if( width <= 0 ) argerror( 4, "width must be postive" );
 | 
			
		||||
                    if( field + width > 32 ) error( "trying to access non-existent bits" );
 | 
			
		||||
 | 
			
		||||
                    int mask = (-1 >>> (32 - width)) << field;
 | 
			
		||||
                    n = (n & ~mask) | ((v << field) & mask);
 | 
			
		||||
                    return bitsToValue( n );
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return NIL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final class Bit32Lib2 extends TwoArgFunction
 | 
			
		||||
    {
 | 
			
		||||
        public LuaValue call( LuaValue arg1, LuaValue arg2 )
 | 
			
		||||
        {
 | 
			
		||||
            switch( opcode )
 | 
			
		||||
            {
 | 
			
		||||
                case 0: // arshift
 | 
			
		||||
                {
 | 
			
		||||
                    int x = arg1.checkint();
 | 
			
		||||
                    int disp = arg2.checkint();
 | 
			
		||||
                    return disp >= 0 ? bitsToValue( x >> disp ) : bitsToValue( x << -disp );
 | 
			
		||||
                }
 | 
			
		||||
                case 1: // lrotate
 | 
			
		||||
                    return rotate( arg1.checkint(), arg2.checkint() );
 | 
			
		||||
                case 2: // lshift
 | 
			
		||||
                    return shift( arg1.checkint(), arg2.checkint() );
 | 
			
		||||
                case 3: // rrotate
 | 
			
		||||
                    return rotate( arg1.checkint(), -arg2.checkint() );
 | 
			
		||||
                case 4: // rshift
 | 
			
		||||
                    return shift( arg1.checkint(), -arg2.checkint() );
 | 
			
		||||
            }
 | 
			
		||||
            return NIL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static LuaValue rotate( int x, int disp )
 | 
			
		||||
    {
 | 
			
		||||
        if( disp < 0 )
 | 
			
		||||
        {
 | 
			
		||||
            disp = -disp & 31;
 | 
			
		||||
            return bitsToValue( (x >>> disp) | (x << (32 - disp)) );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            disp = disp & 31;
 | 
			
		||||
            return bitsToValue( (x << disp) | (x >>> (32 - disp)) );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static LuaValue shift( int x, int disp )
 | 
			
		||||
    {
 | 
			
		||||
        if( disp >= 32 || disp <= -32 )
 | 
			
		||||
        {
 | 
			
		||||
            return ZERO;
 | 
			
		||||
        }
 | 
			
		||||
        else if( disp >= 0 )
 | 
			
		||||
        {
 | 
			
		||||
            return bitsToValue( x << disp );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return bitsToValue( x >>> -disp );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static LuaValue bitsToValue( int x )
 | 
			
		||||
    {
 | 
			
		||||
        return x < 0 ? LuaValue.valueOf( (long) x & 0xFFFFFFFFL ) : LuaInteger.valueOf( x );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,134 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2007-2011 LuaJ. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaTable;
 | 
			
		||||
import org.luaj.vm2.LuaThread;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Subclass of {@link LibFunction} which implements the lua standard {@code coroutine} 
 | 
			
		||||
 * library. 
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * The coroutine library in luaj has the same behavior as the
 | 
			
		||||
 * coroutine library in C, but is implemented using Java Threads to maintain 
 | 
			
		||||
 * the call state between invocations.  Therefore it can be yielded from anywhere, 
 | 
			
		||||
 * similar to the "Coco" yield-from-anywhere patch available for C-based lua.
 | 
			
		||||
 * However, coroutines that are yielded but never resumed to complete their execution
 | 
			
		||||
 * may not be collected by the garbage collector. 
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * Typically, this library is included as part of a call to either 
 | 
			
		||||
 * {@link JsePlatform#standardGlobals()} or {@link JmePlatform#standardGlobals()}
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To instantiate and use it directly, 
 | 
			
		||||
 * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LuaTable _G = new LuaTable();
 | 
			
		||||
 * _G.load(new CoroutineLib());
 | 
			
		||||
 * } </pre>
 | 
			
		||||
 * Doing so will ensure the library is properly initialized 
 | 
			
		||||
 * and loaded into the globals table. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * @see LibFunction
 | 
			
		||||
 * @see JsePlatform
 | 
			
		||||
 * @see JmePlatform
 | 
			
		||||
 * @see <a href="http://www.lua.org/manual/5.1/manual.html#5.2">http://www.lua.org/manual/5.1/manual.html#5.2</a>
 | 
			
		||||
 */
 | 
			
		||||
public class CoroutineLib extends VarArgFunction {
 | 
			
		||||
	
 | 
			
		||||
	private static final int INIT    = 0;
 | 
			
		||||
	private static final int CREATE  = 1;
 | 
			
		||||
	private static final int RESUME  = 2;
 | 
			
		||||
	private static final int RUNNING = 3;
 | 
			
		||||
	private static final int STATUS  = 4;
 | 
			
		||||
	private static final int YIELD   = 5;
 | 
			
		||||
	private static final int WRAP    = 6;
 | 
			
		||||
	private static final int WRAPPED = 7;
 | 
			
		||||
	
 | 
			
		||||
	public CoroutineLib() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private LuaTable init() {
 | 
			
		||||
		LuaTable t = new LuaTable();
 | 
			
		||||
		bind(t, CoroutineLib.class, new  String[] {
 | 
			
		||||
			"create", "resume", "running", "status", "yield", "wrap" },
 | 
			
		||||
			CREATE);
 | 
			
		||||
		env.set("coroutine", t);
 | 
			
		||||
		PackageLib.instance.LOADED.set("coroutine", t);
 | 
			
		||||
		return t;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Varargs invoke(Varargs args) {
 | 
			
		||||
		switch ( opcode ) {
 | 
			
		||||
			case INIT: {
 | 
			
		||||
				return init();
 | 
			
		||||
			}
 | 
			
		||||
			case CREATE: {
 | 
			
		||||
				final LuaValue func = args.checkfunction(1);
 | 
			
		||||
                /* DAN200 START */
 | 
			
		||||
				//return new LuaThread(func, LuaThread.getGlobals() );
 | 
			
		||||
                final LuaThread thread = new LuaThread( func, LuaThread.getGlobals() );
 | 
			
		||||
                LuaThread.getRunning().addChild( thread );
 | 
			
		||||
                return thread;
 | 
			
		||||
                /* DAN200 END */
 | 
			
		||||
			}
 | 
			
		||||
			case RESUME: {
 | 
			
		||||
				final LuaThread t = args.checkthread(1);
 | 
			
		||||
				return t.resume( args.subargs(2) );
 | 
			
		||||
			}
 | 
			
		||||
			case RUNNING: {
 | 
			
		||||
				final LuaThread r = LuaThread.getRunning();
 | 
			
		||||
				return LuaThread.isMainThread(r)? NIL: r;
 | 
			
		||||
			}
 | 
			
		||||
			case STATUS: {
 | 
			
		||||
				return valueOf( args.checkthread(1).getStatus() );
 | 
			
		||||
			}
 | 
			
		||||
			case YIELD: {
 | 
			
		||||
				return LuaThread.yield( args );
 | 
			
		||||
			}
 | 
			
		||||
			case WRAP: {
 | 
			
		||||
				final LuaValue func = args.checkfunction(1);
 | 
			
		||||
				final LuaThread thread = new LuaThread(func, func.getfenv());
 | 
			
		||||
                /* DAN200 START */
 | 
			
		||||
                LuaThread.getRunning().addChild( thread );
 | 
			
		||||
                /* DAN200 END */
 | 
			
		||||
				CoroutineLib cl = new CoroutineLib();
 | 
			
		||||
				cl.setfenv(thread);
 | 
			
		||||
				cl.name = "wrapped";
 | 
			
		||||
				cl.opcode = WRAPPED;
 | 
			
		||||
				return cl;
 | 
			
		||||
			}
 | 
			
		||||
			case WRAPPED: {
 | 
			
		||||
				final LuaThread t = (LuaThread) env;
 | 
			
		||||
				final Varargs result = t.resume( args );
 | 
			
		||||
				if ( result.arg1().toboolean() ) {
 | 
			
		||||
					return result.subargs(2);
 | 
			
		||||
				} else {
 | 
			
		||||
					error( result.arg(2).tojstring() );
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			default:
 | 
			
		||||
				return NONE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,977 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import java.lang.ref.WeakReference;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.Lua;
 | 
			
		||||
import org.luaj.vm2.LuaBoolean;
 | 
			
		||||
import org.luaj.vm2.LuaClosure;
 | 
			
		||||
import org.luaj.vm2.LuaError;
 | 
			
		||||
import org.luaj.vm2.LuaFunction;
 | 
			
		||||
import org.luaj.vm2.LuaNil;
 | 
			
		||||
import org.luaj.vm2.LuaNumber;
 | 
			
		||||
import org.luaj.vm2.LuaString;
 | 
			
		||||
import org.luaj.vm2.LuaTable;
 | 
			
		||||
import org.luaj.vm2.LuaThread;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Print;
 | 
			
		||||
import org.luaj.vm2.Prototype;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Subclass of {@link LibFunction} which implements the lua standard {@code debug} 
 | 
			
		||||
 * library. 
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * The debug library in luaj tries to emulate the behavior of the corresponding C-based lua library.
 | 
			
		||||
 * To do this, it must maintain a separate stack of calls to {@link LuaClosure} and {@link LibFunction} 
 | 
			
		||||
 * instances.  
 | 
			
		||||
 * Especially when lua-to-java bytecode compiling is being used
 | 
			
		||||
 * via a {@link LuaCompiler} such as {@link LuaJC}, 
 | 
			
		||||
 * this cannot be done in all cases.  
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * Typically, this library is included as part of a call to either 
 | 
			
		||||
 * {@link JsePlatform#debugGlobals()} or {@link JmePlatform#debugGlobals()}
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To instantiate and use it directly, 
 | 
			
		||||
 * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LuaTable _G = new LuaTable();
 | 
			
		||||
 * _G.load(new DebugLib());
 | 
			
		||||
 * } </pre>
 | 
			
		||||
 * Doing so will ensure the library is properly initialized 
 | 
			
		||||
 * and loaded into the globals table. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * @see LibFunction
 | 
			
		||||
 * @see JsePlatform
 | 
			
		||||
 * @see JmePlatform
 | 
			
		||||
 * @see <a href="http://www.lua.org/manual/5.1/manual.html#5.9">http://www.lua.org/manual/5.1/manual.html#5.9</a>
 | 
			
		||||
 */
 | 
			
		||||
public class DebugLib extends VarArgFunction {
 | 
			
		||||
	public static final boolean CALLS = (null != System.getProperty("CALLS"));
 | 
			
		||||
	public static final boolean TRACE = (null != System.getProperty("TRACE"));
 | 
			
		||||
 | 
			
		||||
	// leave this unset to allow obfuscators to 
 | 
			
		||||
	// remove it in production builds
 | 
			
		||||
	public static boolean DEBUG_ENABLED;
 | 
			
		||||
 | 
			
		||||
	static final String[] NAMES = {
 | 
			
		||||
		"debug",
 | 
			
		||||
		"getfenv",
 | 
			
		||||
		"gethook",
 | 
			
		||||
		"getinfo",
 | 
			
		||||
		"getlocal",
 | 
			
		||||
		"getmetatable",
 | 
			
		||||
		"getregistry",
 | 
			
		||||
		"getupvalue",
 | 
			
		||||
		"setfenv",
 | 
			
		||||
		"sethook",
 | 
			
		||||
		"setlocal",
 | 
			
		||||
		"setmetatable",
 | 
			
		||||
		"setupvalue",
 | 
			
		||||
		"traceback",
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
	private static final int INIT        	= 0;
 | 
			
		||||
	private static final int DEBUG        	= 1;
 | 
			
		||||
	private static final int GETFENV        = 2;
 | 
			
		||||
	private static final int GETHOOK        = 3;
 | 
			
		||||
	private static final int GETINFO        = 4;
 | 
			
		||||
	private static final int GETLOCAL       = 5;
 | 
			
		||||
	private static final int GETMETATABLE 	= 6;
 | 
			
		||||
	private static final int GETREGISTRY    = 7;
 | 
			
		||||
	private static final int GETUPVALUE    	= 8;
 | 
			
		||||
	private static final int SETFENV        = 9;
 | 
			
		||||
	private static final int SETHOOK        = 10;
 | 
			
		||||
	private static final int SETLOCAL 		= 11;
 | 
			
		||||
	private static final int SETMETATABLE   = 12;
 | 
			
		||||
	private static final int SETUPVALUE    	= 13;
 | 
			
		||||
	private static final int TRACEBACK    	= 14;
 | 
			
		||||
 | 
			
		||||
	/* maximum stack for a Lua function */
 | 
			
		||||
	private static final int MAXSTACK = 250;
 | 
			
		||||
	
 | 
			
		||||
	private static final LuaString LUA        = valueOf("Lua");  
 | 
			
		||||
	private static final LuaString JAVA       = valueOf("Java");  
 | 
			
		||||
	private static final LuaString QMARK      = valueOf("?");  
 | 
			
		||||
	private static final LuaString GLOBAL     = valueOf("global");  
 | 
			
		||||
	private static final LuaString LOCAL      = valueOf("local");  
 | 
			
		||||
	private static final LuaString METHOD     = valueOf("method");  
 | 
			
		||||
	private static final LuaString UPVALUE    = valueOf("upvalue");  
 | 
			
		||||
	private static final LuaString FIELD      = valueOf("field");
 | 
			
		||||
	private static final LuaString CALL       = valueOf("call");  
 | 
			
		||||
	private static final LuaString LINE       = valueOf("line");  
 | 
			
		||||
	private static final LuaString COUNT      = valueOf("count");  
 | 
			
		||||
	private static final LuaString RETURN     = valueOf("return");  
 | 
			
		||||
	private static final LuaString TAILRETURN = valueOf("tail return");
 | 
			
		||||
	
 | 
			
		||||
	private static final LuaString FUNC            = valueOf("func");  
 | 
			
		||||
	private static final LuaString NUPS            = valueOf("nups");  
 | 
			
		||||
	private static final LuaString NAME            = valueOf("name");  
 | 
			
		||||
	private static final LuaString NAMEWHAT        = valueOf("namewhat");  
 | 
			
		||||
	private static final LuaString WHAT            = valueOf("what");  
 | 
			
		||||
	private static final LuaString SOURCE          = valueOf("source");  
 | 
			
		||||
	private static final LuaString SHORT_SRC       = valueOf("short_src");  
 | 
			
		||||
	private static final LuaString LINEDEFINED     = valueOf("linedefined");  
 | 
			
		||||
	private static final LuaString LASTLINEDEFINED = valueOf("lastlinedefined");  
 | 
			
		||||
	private static final LuaString CURRENTLINE     = valueOf("currentline");  
 | 
			
		||||
	private static final LuaString ACTIVELINES     = valueOf("activelines");  
 | 
			
		||||
 | 
			
		||||
	public DebugLib() {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private LuaTable init() {
 | 
			
		||||
		DEBUG_ENABLED = true;
 | 
			
		||||
		LuaTable t = new LuaTable();
 | 
			
		||||
		bind(t, DebugLib.class, NAMES, DEBUG);
 | 
			
		||||
		env.set("debug", t);
 | 
			
		||||
		PackageLib.instance.LOADED.set("debug", t);
 | 
			
		||||
		return t;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Varargs invoke(Varargs args) {
 | 
			
		||||
		switch ( opcode ) {
 | 
			
		||||
		case INIT:         return init();
 | 
			
		||||
		case DEBUG:        return _debug(args);
 | 
			
		||||
		case GETFENV:      return _getfenv(args);
 | 
			
		||||
		case GETHOOK:      return _gethook(args);
 | 
			
		||||
		case GETINFO:      return _getinfo(args,this);
 | 
			
		||||
		case GETLOCAL:     return _getlocal(args);
 | 
			
		||||
		case GETMETATABLE: return _getmetatable(args);
 | 
			
		||||
		case GETREGISTRY:  return _getregistry(args);
 | 
			
		||||
		case GETUPVALUE:   return _getupvalue(args);
 | 
			
		||||
		case SETFENV:      return _setfenv(args);
 | 
			
		||||
		case SETHOOK:      return _sethook(args);
 | 
			
		||||
		case SETLOCAL:     return _setlocal(args);
 | 
			
		||||
		case SETMETATABLE: return _setmetatable(args);
 | 
			
		||||
		case SETUPVALUE:   return _setupvalue(args);
 | 
			
		||||
		case TRACEBACK:    return _traceback(args);
 | 
			
		||||
		default:           return NONE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// ------------------------ Debug Info management --------------------------
 | 
			
		||||
	// 
 | 
			
		||||
	// when DEBUG_ENABLED is set to true, these functions will be called 
 | 
			
		||||
	// by Closure instances as they process bytecodes.
 | 
			
		||||
	//
 | 
			
		||||
	// Each thread will get a DebugState attached to it by the debug library
 | 
			
		||||
	// which will track function calls, hook functions, etc.
 | 
			
		||||
	// 
 | 
			
		||||
	static class DebugInfo {
 | 
			
		||||
		LuaValue func;
 | 
			
		||||
		LuaClosure closure;
 | 
			
		||||
		LuaValue[] stack;
 | 
			
		||||
		Varargs varargs, extras;
 | 
			
		||||
		int pc, top;
 | 
			
		||||
		
 | 
			
		||||
		private DebugInfo() {			
 | 
			
		||||
			func = NIL;
 | 
			
		||||
		}
 | 
			
		||||
		private DebugInfo(LuaValue func) {
 | 
			
		||||
			pc = -1;
 | 
			
		||||
			setfunction( func );
 | 
			
		||||
		}
 | 
			
		||||
		void setargs(Varargs varargs, LuaValue[] stack) {
 | 
			
		||||
			this.varargs = varargs;
 | 
			
		||||
			this.stack = stack;
 | 
			
		||||
		}
 | 
			
		||||
		void setfunction( LuaValue func ) {
 | 
			
		||||
			this.func = func;
 | 
			
		||||
			this.closure = (func instanceof LuaClosure? (LuaClosure) func: null);
 | 
			
		||||
		}
 | 
			
		||||
		void clear() {
 | 
			
		||||
			func = NIL;
 | 
			
		||||
			closure = null;
 | 
			
		||||
			stack = null;
 | 
			
		||||
			varargs = extras = null;
 | 
			
		||||
			pc = top = 0;
 | 
			
		||||
		}
 | 
			
		||||
		public void bytecode(int pc, Varargs extras, int top) {
 | 
			
		||||
			this.pc = pc;
 | 
			
		||||
			this.top = top;
 | 
			
		||||
			this.extras = extras;
 | 
			
		||||
		}
 | 
			
		||||
		public int currentline() {
 | 
			
		||||
			if ( closure == null ) return -1;
 | 
			
		||||
			int[] li = closure.p.lineinfo;
 | 
			
		||||
			return li==null || pc<0 || pc>=li.length? -1: li[pc]; 
 | 
			
		||||
		}
 | 
			
		||||
		public LuaString[] getfunckind() {
 | 
			
		||||
			if ( closure == null || pc<0 ) return null;
 | 
			
		||||
			int stackpos = (closure.p.code[pc] >> 6) & 0xff; 
 | 
			
		||||
			return getobjname(this, stackpos);
 | 
			
		||||
		}
 | 
			
		||||
		public String sourceline() {
 | 
			
		||||
			if ( closure == null ) return func.tojstring();
 | 
			
		||||
			String s = closure.p.source.tojstring();
 | 
			
		||||
			int line = currentline();
 | 
			
		||||
			return (s.startsWith("@")||s.startsWith("=")? s.substring(1): s) + ":" + line;
 | 
			
		||||
		}
 | 
			
		||||
		public String tracename() {
 | 
			
		||||
			// if ( func != null )
 | 
			
		||||
			// 	return func.tojstring();
 | 
			
		||||
			LuaString[] kind = getfunckind();
 | 
			
		||||
			if ( kind == null )
 | 
			
		||||
				return "function ?";
 | 
			
		||||
			return "function "+kind[0].tojstring();
 | 
			
		||||
		}
 | 
			
		||||
		public LuaString getlocalname(int index) {
 | 
			
		||||
			if ( closure == null ) return null;
 | 
			
		||||
			return closure.p.getlocalname(index, pc);
 | 
			
		||||
		}
 | 
			
		||||
		public String tojstring() {
 | 
			
		||||
			return tracename()+" "+sourceline();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** DebugState is associated with a Thread */
 | 
			
		||||
	static class DebugState {
 | 
			
		||||
		private final WeakReference thread_ref;
 | 
			
		||||
		private int debugCalls = 0;
 | 
			
		||||
		private DebugInfo[] debugInfo = new DebugInfo[LuaThread.MAX_CALLSTACK+1];
 | 
			
		||||
		private LuaValue hookfunc;
 | 
			
		||||
		private boolean hookcall,hookline,hookrtrn,inhook;
 | 
			
		||||
		private int hookcount,hookcodes;
 | 
			
		||||
		private int line;
 | 
			
		||||
		DebugState(LuaThread thread) {
 | 
			
		||||
			this.thread_ref = new WeakReference(thread);
 | 
			
		||||
		}
 | 
			
		||||
		public DebugInfo nextInfo() {
 | 
			
		||||
			DebugInfo di = debugInfo[debugCalls];
 | 
			
		||||
			if ( di == null ) 
 | 
			
		||||
				debugInfo[debugCalls] = di = new DebugInfo();
 | 
			
		||||
			return di;
 | 
			
		||||
		}
 | 
			
		||||
		public DebugInfo pushInfo( int calls ) {
 | 
			
		||||
			while ( debugCalls < calls ) {
 | 
			
		||||
				nextInfo();
 | 
			
		||||
				++debugCalls;
 | 
			
		||||
			}
 | 
			
		||||
			return debugInfo[debugCalls-1];
 | 
			
		||||
		}
 | 
			
		||||
		public void popInfo(int calls) {
 | 
			
		||||
			while ( debugCalls > calls )
 | 
			
		||||
				debugInfo[--debugCalls].clear();
 | 
			
		||||
		}
 | 
			
		||||
		void callHookFunc(DebugState ds, LuaString type, LuaValue arg) {
 | 
			
		||||
			if ( inhook || hookfunc == null )
 | 
			
		||||
				return;
 | 
			
		||||
			inhook = true;
 | 
			
		||||
			try {
 | 
			
		||||
				int n = debugCalls;
 | 
			
		||||
				ds.nextInfo().setargs( arg, null );
 | 
			
		||||
				ds.pushInfo(n+1).setfunction(hookfunc);
 | 
			
		||||
				try {
 | 
			
		||||
					hookfunc.call(type,arg);
 | 
			
		||||
				} finally {
 | 
			
		||||
					ds.popInfo(n);
 | 
			
		||||
				}
 | 
			
		||||
			} catch ( Exception e ) {
 | 
			
		||||
				e.printStackTrace();
 | 
			
		||||
			} finally {
 | 
			
		||||
				inhook = false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public void sethook(LuaValue func, boolean call, boolean line, boolean rtrn, int count) {
 | 
			
		||||
			this.hookcount = count;
 | 
			
		||||
			this.hookcall = call;
 | 
			
		||||
			this.hookline = line;
 | 
			
		||||
			this.hookrtrn = rtrn;
 | 
			
		||||
			this.hookfunc = func;
 | 
			
		||||
		}
 | 
			
		||||
		DebugInfo getDebugInfo() {
 | 
			
		||||
			try {
 | 
			
		||||
				return debugInfo[debugCalls-1];
 | 
			
		||||
			} catch ( Exception e ) {
 | 
			
		||||
				if ( debugCalls <= 0 )
 | 
			
		||||
					return debugInfo[debugCalls++] = new DebugInfo();
 | 
			
		||||
				return null;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		DebugInfo getDebugInfo(int level) {
 | 
			
		||||
			return level < 0 || level >= debugCalls? null: debugInfo[debugCalls-level-1];
 | 
			
		||||
		}
 | 
			
		||||
		public DebugInfo findDebugInfo(LuaValue func) {			
 | 
			
		||||
			for ( int i=debugCalls; --i>=0; ) {
 | 
			
		||||
				if ( debugInfo[i].func == func ) {
 | 
			
		||||
					return debugInfo[i];
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return new DebugInfo(func);
 | 
			
		||||
		}
 | 
			
		||||
		public String tojstring() {
 | 
			
		||||
			LuaThread thread = (LuaThread) thread_ref.get();
 | 
			
		||||
			return thread != null? DebugLib.traceback(thread, 0): "orphaned thread";
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	static DebugState getDebugState( LuaThread thread ) {
 | 
			
		||||
		if ( thread.debugState == null )
 | 
			
		||||
			thread.debugState = new DebugState(thread);
 | 
			
		||||
		return (DebugState) thread.debugState;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	static DebugState getDebugState() {
 | 
			
		||||
		return getDebugState( LuaThread.getRunning() );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Called by Closures to set up stack and arguments to next call */
 | 
			
		||||
	public static void debugSetupCall(Varargs args, LuaValue[] stack) {
 | 
			
		||||
		DebugState ds = getDebugState();
 | 
			
		||||
		if ( ds.inhook )
 | 
			
		||||
			return;
 | 
			
		||||
		ds.nextInfo().setargs( args, stack );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Called by Closures and recursing java functions on entry
 | 
			
		||||
	 * @param thread the thread for the call 
 | 
			
		||||
	 * @param calls the number of calls in the call stack
 | 
			
		||||
	 * @param func the function called
 | 
			
		||||
	 */
 | 
			
		||||
	public static void debugOnCall(LuaThread thread, int calls, LuaFunction func) {
 | 
			
		||||
		DebugState ds = getDebugState();
 | 
			
		||||
		if ( ds.inhook )
 | 
			
		||||
			return;
 | 
			
		||||
		DebugInfo di = ds.pushInfo(calls);
 | 
			
		||||
		di.setfunction( func );
 | 
			
		||||
		if(CALLS)System.out.println("calling "+func);		
 | 
			
		||||
		if ( ds.hookcall )
 | 
			
		||||
			ds.callHookFunc( ds, CALL, LuaValue.NIL );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Called by Closures and recursing java functions on return 
 | 
			
		||||
	 * @param thread the thread for the call 
 | 
			
		||||
	 * @param calls the number of calls in the call stack
 | 
			
		||||
	 */
 | 
			
		||||
	public static void debugOnReturn(LuaThread thread, int calls) {
 | 
			
		||||
		DebugState ds = getDebugState(thread);
 | 
			
		||||
		if ( ds.inhook )
 | 
			
		||||
			return;
 | 
			
		||||
		if(CALLS)System.out.println("returning");		
 | 
			
		||||
		try {
 | 
			
		||||
			if ( ds.hookrtrn )
 | 
			
		||||
				ds.callHookFunc( ds, RETURN, LuaValue.NIL );
 | 
			
		||||
		} finally {
 | 
			
		||||
			getDebugState().popInfo(calls);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Called by Closures on bytecode execution */
 | 
			
		||||
	public static void debugBytecode( int pc, Varargs extras, int top ) {
 | 
			
		||||
		DebugState ds = getDebugState();
 | 
			
		||||
		if ( ds.inhook )
 | 
			
		||||
			return;
 | 
			
		||||
		DebugInfo di = ds.getDebugInfo();
 | 
			
		||||
		if(TRACE)Print.printState(di.closure, pc, di.stack, top, di.varargs);		
 | 
			
		||||
		di.bytecode( pc, extras, top );
 | 
			
		||||
		if ( ds.hookcount > 0 ) {
 | 
			
		||||
			if ( ++ds.hookcodes >= ds.hookcount ) {
 | 
			
		||||
				ds.hookcodes = 0;
 | 
			
		||||
				ds.callHookFunc( ds, COUNT, LuaValue.NIL );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if ( ds.hookline ) {
 | 
			
		||||
			int newline = di.currentline();
 | 
			
		||||
			if ( newline != ds.line ) {
 | 
			
		||||
				int c = di.closure.p.code[pc];
 | 
			
		||||
				if ( (c&0x3f) != Lua.OP_JMP || ((c>>>14)-0x1ffff) >= 0 ) {
 | 
			
		||||
					ds.line = newline;
 | 
			
		||||
					ds.callHookFunc( ds, LINE, LuaValue.valueOf(newline) );
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// ------------------- library function implementations -----------------
 | 
			
		||||
	
 | 
			
		||||
	// j2se subclass may wish to override and provide actual console here. 
 | 
			
		||||
	// j2me platform has not System.in to provide console.
 | 
			
		||||
	static Varargs _debug(Varargs args) {
 | 
			
		||||
		return NONE;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	static Varargs _gethook(Varargs args) {
 | 
			
		||||
		int a=1;
 | 
			
		||||
		LuaThread thread = args.isthread(a)? args.checkthread(a++): LuaThread.getRunning(); 
 | 
			
		||||
		DebugState ds = getDebugState(thread);
 | 
			
		||||
		return varargsOf(
 | 
			
		||||
				ds.hookfunc,
 | 
			
		||||
				valueOf((ds.hookcall?"c":"")+(ds.hookline?"l":"")+(ds.hookrtrn?"r":"")),
 | 
			
		||||
				valueOf(ds.hookcount));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static Varargs _sethook(Varargs args) {
 | 
			
		||||
		int a=1;
 | 
			
		||||
		LuaThread thread = args.isthread(a)? args.checkthread(a++): LuaThread.getRunning(); 
 | 
			
		||||
		LuaValue func    = args.optfunction(a++, null);
 | 
			
		||||
		String str       = args.optjstring(a++,"");
 | 
			
		||||
		int count        = args.optint(a++,0);
 | 
			
		||||
		boolean call=false,line=false,rtrn=false;
 | 
			
		||||
		for ( int i=0; i<str.length(); i++ )
 | 
			
		||||
			switch ( str.charAt(i) ) {
 | 
			
		||||
				case 'c': call=true; break;
 | 
			
		||||
				case 'l': line=true; break;
 | 
			
		||||
				case 'r': rtrn=true; break;
 | 
			
		||||
			}
 | 
			
		||||
		getDebugState(thread).sethook(func, call, line, rtrn, count);
 | 
			
		||||
		return NONE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static Varargs _getfenv(Varargs args) {
 | 
			
		||||
		LuaValue object = args.arg1();
 | 
			
		||||
		LuaValue env = object.getfenv();
 | 
			
		||||
		return env!=null? env: LuaValue.NIL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static Varargs _setfenv(Varargs args) {
 | 
			
		||||
		LuaValue object = args.arg1();
 | 
			
		||||
		LuaTable table = args.checktable(2);
 | 
			
		||||
		object.setfenv(table);
 | 
			
		||||
		return object;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected static Varargs _getinfo(Varargs args, LuaValue level0func) {
 | 
			
		||||
		int a=1;
 | 
			
		||||
		LuaThread thread = args.isthread(a)? args.checkthread(a++): LuaThread.getRunning(); 
 | 
			
		||||
		LuaValue func = args.arg(a++);
 | 
			
		||||
		String what = args.optjstring(a++, "nSluf");
 | 
			
		||||
		
 | 
			
		||||
		// find the stack info
 | 
			
		||||
		DebugState ds = getDebugState( thread );
 | 
			
		||||
		DebugInfo di = null;
 | 
			
		||||
		if ( func.isnumber() ) {
 | 
			
		||||
			int level = func.checkint();
 | 
			
		||||
			di = level>0? 
 | 
			
		||||
				ds.getDebugInfo(level-1):
 | 
			
		||||
				new DebugInfo( level0func );
 | 
			
		||||
		} else {			
 | 
			
		||||
			di = ds.findDebugInfo( func.checkfunction() );
 | 
			
		||||
		}
 | 
			
		||||
		if ( di == null )
 | 
			
		||||
			return NIL;
 | 
			
		||||
 | 
			
		||||
		// start a table
 | 
			
		||||
		LuaTable info = new LuaTable();
 | 
			
		||||
		LuaClosure c = di.closure;
 | 
			
		||||
		for (int i = 0, j = what.length(); i < j; i++) {
 | 
			
		||||
			switch (what.charAt(i)) {
 | 
			
		||||
				case 'S': {
 | 
			
		||||
					if ( c != null ) {
 | 
			
		||||
						Prototype p = c.p;
 | 
			
		||||
						info.set(WHAT, LUA);
 | 
			
		||||
						info.set(SOURCE, p.source);
 | 
			
		||||
						info.set(SHORT_SRC, valueOf(sourceshort(p)));
 | 
			
		||||
						info.set(LINEDEFINED, valueOf(p.linedefined));
 | 
			
		||||
						info.set(LASTLINEDEFINED, valueOf(p.lastlinedefined));
 | 
			
		||||
					} else {
 | 
			
		||||
						String shortName = di.func.tojstring();
 | 
			
		||||
						LuaString name = LuaString.valueOf("[Java] "+shortName);
 | 
			
		||||
						info.set(WHAT, JAVA);
 | 
			
		||||
						info.set(SOURCE, name);
 | 
			
		||||
						info.set(SHORT_SRC, valueOf(shortName));
 | 
			
		||||
						info.set(LINEDEFINED, LuaValue.MINUSONE);
 | 
			
		||||
						info.set(LASTLINEDEFINED, LuaValue.MINUSONE);
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case 'l': {
 | 
			
		||||
					int line = di.currentline();
 | 
			
		||||
					info.set( CURRENTLINE, valueOf(line) );
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case 'u': {
 | 
			
		||||
					info.set(NUPS, valueOf(c!=null? c.p.nups: 0));
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case 'n': {
 | 
			
		||||
					LuaString[] kind = di.getfunckind();
 | 
			
		||||
					info.set(NAME, kind!=null? kind[0]: QMARK);
 | 
			
		||||
					info.set(NAMEWHAT, kind!=null? kind[1]: EMPTYSTRING);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case 'f': {
 | 
			
		||||
					info.set( FUNC, di.func );
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case 'L': {
 | 
			
		||||
					LuaTable lines = new LuaTable();
 | 
			
		||||
					info.set(ACTIVELINES, lines);
 | 
			
		||||
//					if ( di.luainfo != null ) {
 | 
			
		||||
//						int line = di.luainfo.currentline();
 | 
			
		||||
//						if ( line >= 0 )
 | 
			
		||||
//							lines.set(1, IntValue.valueOf(line));
 | 
			
		||||
//					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return info;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static String sourceshort(Prototype p) {
 | 
			
		||||
		String name = p.source.tojstring();
 | 
			
		||||
        if ( name.startsWith("@") || name.startsWith("=") )
 | 
			
		||||
			name = name.substring(1);
 | 
			
		||||
		else if ( name.startsWith("\033") )
 | 
			
		||||
			name = "binary string";
 | 
			
		||||
        return name;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	static Varargs _getlocal(Varargs args) {
 | 
			
		||||
		int a=1;
 | 
			
		||||
		LuaThread thread = args.isthread(a)? args.checkthread(a++): LuaThread.getRunning(); 
 | 
			
		||||
		int level = args.checkint(a++);
 | 
			
		||||
		int local = args.checkint(a++);
 | 
			
		||||
		
 | 
			
		||||
		DebugState ds = getDebugState(thread); 
 | 
			
		||||
		DebugInfo di = ds.getDebugInfo(level-1);
 | 
			
		||||
		LuaString name = (di!=null? di.getlocalname(local): null);
 | 
			
		||||
		if ( name != null ) {
 | 
			
		||||
			LuaValue value = di.stack[local-1];
 | 
			
		||||
			return varargsOf( name, value );
 | 
			
		||||
		} else {
 | 
			
		||||
			return NIL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static Varargs _setlocal(Varargs args) {
 | 
			
		||||
		int a=1;
 | 
			
		||||
		LuaThread thread = args.isthread(a)? args.checkthread(a++): LuaThread.getRunning(); 
 | 
			
		||||
		int level = args.checkint(a++);
 | 
			
		||||
		int local = args.checkint(a++);
 | 
			
		||||
		LuaValue value = args.arg(a++);
 | 
			
		||||
		
 | 
			
		||||
		DebugState ds = getDebugState(thread); 
 | 
			
		||||
		DebugInfo di = ds.getDebugInfo(level-1);
 | 
			
		||||
		LuaString name = (di!=null? di.getlocalname(local): null);
 | 
			
		||||
		if ( name != null ) {
 | 
			
		||||
			di.stack[local-1] = value;
 | 
			
		||||
			return name;
 | 
			
		||||
		} else {
 | 
			
		||||
			return NIL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static LuaValue _getmetatable(Varargs args) {
 | 
			
		||||
		LuaValue object = args.arg(1);
 | 
			
		||||
		LuaValue mt = object.getmetatable();
 | 
			
		||||
		return mt!=null? mt: NIL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static Varargs _setmetatable(Varargs args) {
 | 
			
		||||
		LuaValue object = args.arg(1);
 | 
			
		||||
		try {
 | 
			
		||||
			LuaValue mt = args.opttable(2, null);
 | 
			
		||||
			switch ( object.type() ) {
 | 
			
		||||
				case TNIL:      LuaNil.s_metatable      = mt; break;
 | 
			
		||||
				case TNUMBER:   LuaNumber.s_metatable   = mt; break;
 | 
			
		||||
				case TBOOLEAN:  LuaBoolean.s_metatable  = mt; break;
 | 
			
		||||
				case TSTRING:   LuaString.s_metatable   = mt; break;
 | 
			
		||||
				case TFUNCTION: LuaFunction.s_metatable = mt; break;
 | 
			
		||||
				case TTHREAD:   LuaThread.s_metatable   = mt; break;
 | 
			
		||||
				default: object.setmetatable( mt );
 | 
			
		||||
			}
 | 
			
		||||
			return LuaValue.TRUE;
 | 
			
		||||
		} catch ( LuaError e ) {
 | 
			
		||||
			return varargsOf(FALSE, valueOf(e.toString()));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static Varargs _getregistry(Varargs args) {
 | 
			
		||||
		return new LuaTable();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static LuaString findupvalue(LuaClosure c, int up) {
 | 
			
		||||
		if ( c.upValues != null && up > 0 && up <= c.upValues.length ) {
 | 
			
		||||
			if ( c.p.upvalues != null && up <= c.p.upvalues.length )
 | 
			
		||||
				return c.p.upvalues[up-1];
 | 
			
		||||
			else
 | 
			
		||||
				return LuaString.valueOf( "."+up );
 | 
			
		||||
		}
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static Varargs _getupvalue(Varargs args) {
 | 
			
		||||
		LuaValue func = args.checkfunction(1);
 | 
			
		||||
		int up = args.checkint(2);
 | 
			
		||||
		if ( func instanceof LuaClosure ) {
 | 
			
		||||
			LuaClosure c = (LuaClosure) func;
 | 
			
		||||
			LuaString name = findupvalue(c, up);
 | 
			
		||||
			if ( name != null ) {
 | 
			
		||||
				return varargsOf(name, c.upValues[up-1].getValue() );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return NIL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static LuaValue _setupvalue(Varargs args) {
 | 
			
		||||
		LuaValue func = args.checkfunction(1);
 | 
			
		||||
		int up = args.checkint(2);
 | 
			
		||||
		LuaValue value = args.arg(3);
 | 
			
		||||
		if ( func instanceof LuaClosure ) {
 | 
			
		||||
			LuaClosure c = (LuaClosure) func;
 | 
			
		||||
			LuaString name = findupvalue(c, up);
 | 
			
		||||
			if ( name != null ) {
 | 
			
		||||
				c.upValues[up-1].setValue(value);
 | 
			
		||||
				return name;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return NIL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static LuaValue _traceback(Varargs args) {
 | 
			
		||||
		int a=1;
 | 
			
		||||
		LuaThread thread = args.isthread(a)? args.checkthread(a++): LuaThread.getRunning(); 
 | 
			
		||||
		String message = args.optjstring(a++, null);
 | 
			
		||||
		int level = args.optint(a++,1);
 | 
			
		||||
		String tb = DebugLib.traceback(thread, level-1);
 | 
			
		||||
		return valueOf(message!=null? message+"\n"+tb: tb);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// =================== public utilities ====================
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Get a traceback as a string for the current thread 
 | 
			
		||||
	 */
 | 
			
		||||
	public static String traceback(int level) {
 | 
			
		||||
		return traceback(LuaThread.getRunning(), level);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get a traceback for a particular thread.
 | 
			
		||||
	 * @param thread LuaThread to provide stack trace for
 | 
			
		||||
	 * @param level 0-based level to start reporting on
 | 
			
		||||
	 * @return String containing the stack trace.
 | 
			
		||||
	 */
 | 
			
		||||
	public static String traceback(LuaThread thread, int level) {
 | 
			
		||||
		StringBuffer sb = new StringBuffer();
 | 
			
		||||
		DebugState ds = getDebugState(thread);
 | 
			
		||||
		sb.append( "stack traceback:" );
 | 
			
		||||
		DebugInfo di = ds.getDebugInfo(level);
 | 
			
		||||
		if ( di != null ) {
 | 
			
		||||
			sb.append( "\n\t" );
 | 
			
		||||
			sb.append( di.sourceline() );
 | 
			
		||||
			sb.append( " in " );
 | 
			
		||||
			while ( (di = ds.getDebugInfo(++level)) != null ) {
 | 
			
		||||
				sb.append( di.tracename() );
 | 
			
		||||
				sb.append( "\n\t" );
 | 
			
		||||
				sb.append( di.sourceline() );
 | 
			
		||||
				sb.append( " in " );
 | 
			
		||||
			}
 | 
			
		||||
			sb.append( "main chunk" );
 | 
			
		||||
		}
 | 
			
		||||
		return sb.toString();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get file and line for the nearest calling closure.
 | 
			
		||||
	 * @return String identifying the file and line of the nearest lua closure,
 | 
			
		||||
	 * or the function name of the Java call if no closure is being called.
 | 
			
		||||
	 */
 | 
			
		||||
	public static String fileline() {
 | 
			
		||||
		DebugState ds = getDebugState(LuaThread.getRunning());
 | 
			
		||||
		DebugInfo di;
 | 
			
		||||
		for ( int i=0, n=ds.debugCalls; i<n; i++ ) {
 | 
			
		||||
			di = ds.getDebugInfo(i);
 | 
			
		||||
			if ( di != null && di.func.isclosure() )
 | 
			
		||||
				return di.sourceline();
 | 
			
		||||
		}
 | 
			
		||||
		return fileline(0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get file and line for a particular level, even if it is a java function.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param level 0-based index of level to get
 | 
			
		||||
	 * @return String containing file and line info if available
 | 
			
		||||
	 */
 | 
			
		||||
	public static String fileline(int level) {
 | 
			
		||||
		DebugState ds = getDebugState(LuaThread.getRunning());
 | 
			
		||||
		DebugInfo di = ds.getDebugInfo(level);
 | 
			
		||||
		return di!=null? di.sourceline(): null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// =======================================================
 | 
			
		||||
	
 | 
			
		||||
	static void lua_assert(boolean x) {
 | 
			
		||||
		if (!x) throw new RuntimeException("lua_assert failed");
 | 
			
		||||
	}	
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	// return StrValue[] { name, namewhat } if found, null if not
 | 
			
		||||
	static LuaString[] getobjname(DebugInfo di, int stackpos) {
 | 
			
		||||
		LuaString name;
 | 
			
		||||
		if (di.closure != null) { /* a Lua function? */
 | 
			
		||||
			Prototype p = di.closure.p;
 | 
			
		||||
			int pc = di.pc; // currentpc(L, ci);
 | 
			
		||||
			int i;// Instruction i;
 | 
			
		||||
			name = p.getlocalname(stackpos + 1, pc);
 | 
			
		||||
			if (name != null) /* is a local? */
 | 
			
		||||
				return new LuaString[] { name, LOCAL };
 | 
			
		||||
			i = symbexec(p, pc, stackpos); /* try symbolic execution */
 | 
			
		||||
			lua_assert(pc != -1);
 | 
			
		||||
			switch (Lua.GET_OPCODE(i)) {
 | 
			
		||||
			case Lua.OP_GETGLOBAL: {
 | 
			
		||||
				int g = Lua.GETARG_Bx(i); /* global index */
 | 
			
		||||
				// lua_assert(p.k[g].isString());
 | 
			
		||||
				return new LuaString[] { p.k[g].strvalue(), GLOBAL };
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_MOVE: {
 | 
			
		||||
				int a = Lua.GETARG_A(i);
 | 
			
		||||
				int b = Lua.GETARG_B(i); /* move from `b' to `a' */
 | 
			
		||||
				if (b < a)
 | 
			
		||||
					return getobjname(di, b); /* get name for `b' */
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_GETTABLE: {
 | 
			
		||||
				int k = Lua.GETARG_C(i); /* key index */
 | 
			
		||||
				name = kname(p, k);
 | 
			
		||||
				return new LuaString[] { name, FIELD };
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_GETUPVAL: {
 | 
			
		||||
				int u = Lua.GETARG_B(i); /* upvalue index */
 | 
			
		||||
				name = u < p.upvalues.length ? p.upvalues[u] : QMARK;
 | 
			
		||||
				return new LuaString[] { name, UPVALUE };
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_SELF: {
 | 
			
		||||
				int k = Lua.GETARG_C(i); /* key index */
 | 
			
		||||
				name = kname(p, k);
 | 
			
		||||
				return new LuaString[] { name, METHOD };
 | 
			
		||||
			}
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return null; /* no useful name found */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static LuaString kname(Prototype p, int c) {
 | 
			
		||||
		if (Lua.ISK(c) && p.k[Lua.INDEXK(c)].isstring())
 | 
			
		||||
			return p.k[Lua.INDEXK(c)].strvalue();
 | 
			
		||||
		else
 | 
			
		||||
			return QMARK;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static boolean checkreg(Prototype pt,int reg)	{
 | 
			
		||||
		return (reg < pt.maxstacksize);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static boolean precheck(Prototype pt) {
 | 
			
		||||
		if (!(pt.maxstacksize <= MAXSTACK)) return false;
 | 
			
		||||
		lua_assert(pt.numparams + (pt.is_vararg & Lua.VARARG_HASARG) <= pt.maxstacksize);
 | 
			
		||||
		lua_assert((pt.is_vararg & Lua.VARARG_NEEDSARG) == 0
 | 
			
		||||
				|| (pt.is_vararg & Lua.VARARG_HASARG) != 0);
 | 
			
		||||
		if (!(pt.upvalues.length <= pt.nups)) return false;
 | 
			
		||||
		if (!(pt.lineinfo.length == pt.code.length || pt.lineinfo.length == 0)) return false;
 | 
			
		||||
		if (!(Lua.GET_OPCODE(pt.code[pt.code.length - 1]) == Lua.OP_RETURN)) return false;
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static boolean checkopenop(Prototype pt,int pc) {
 | 
			
		||||
		int i = pt.code[(pc)+1];
 | 
			
		||||
		switch (Lua.GET_OPCODE(i)) {
 | 
			
		||||
		case Lua.OP_CALL:
 | 
			
		||||
		case Lua.OP_TAILCALL:
 | 
			
		||||
		case Lua.OP_RETURN:
 | 
			
		||||
		case Lua.OP_SETLIST: {
 | 
			
		||||
			if (!(Lua.GETARG_B(i) == 0)) return false;
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		default:
 | 
			
		||||
			return false; /* invalid instruction after an open call */
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	//static int checkArgMode (Prototype pt, int r, enum OpArgMask mode) {
 | 
			
		||||
	static boolean checkArgMode (Prototype pt, int r, int mode) {
 | 
			
		||||
		switch (mode) {
 | 
			
		||||
			case Lua.OpArgN: if (!(r == 0)) return false; break;
 | 
			
		||||
			case Lua.OpArgU: break;
 | 
			
		||||
			case Lua.OpArgR: checkreg(pt, r); break;
 | 
			
		||||
			case Lua.OpArgK:
 | 
			
		||||
				if (!(Lua.ISK(r) ? Lua.INDEXK(r) < pt.k.length : r < pt.maxstacksize)) return false;
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// return last instruction, or 0 if error
 | 
			
		||||
	static int symbexec(Prototype pt, int lastpc, int reg) {
 | 
			
		||||
		int pc;
 | 
			
		||||
		int last; /* stores position of last instruction that changed `reg' */
 | 
			
		||||
		last = pt.code.length - 1; /*
 | 
			
		||||
									 * points to final return (a `neutral'
 | 
			
		||||
									 * instruction)
 | 
			
		||||
									 */
 | 
			
		||||
		if (!(precheck(pt))) return 0;
 | 
			
		||||
		for (pc = 0; pc < lastpc; pc++) {
 | 
			
		||||
			int i = pt.code[pc];
 | 
			
		||||
			int op = Lua.GET_OPCODE(i);
 | 
			
		||||
			int a = Lua.GETARG_A(i);
 | 
			
		||||
			int b = 0;
 | 
			
		||||
			int c = 0;
 | 
			
		||||
			if (!(op < Lua.NUM_OPCODES)) return 0;
 | 
			
		||||
			if (!checkreg(pt, a)) return 0;
 | 
			
		||||
			switch (Lua.getOpMode(op)) {
 | 
			
		||||
			case Lua.iABC: {
 | 
			
		||||
				b = Lua.GETARG_B(i);
 | 
			
		||||
				c = Lua.GETARG_C(i);
 | 
			
		||||
				if (!(checkArgMode(pt, b, Lua.getBMode(op)))) return 0;
 | 
			
		||||
				if (!(checkArgMode(pt, c, Lua.getCMode(op)))) return 0;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.iABx: {
 | 
			
		||||
				b = Lua.GETARG_Bx(i);
 | 
			
		||||
				if (Lua.getBMode(op) == Lua.OpArgK)
 | 
			
		||||
					if (!(b < pt.k.length)) return 0;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.iAsBx: {
 | 
			
		||||
				b = Lua.GETARG_sBx(i);
 | 
			
		||||
				if (Lua.getBMode(op) == Lua.OpArgR) {
 | 
			
		||||
					int dest = pc + 1 + b;
 | 
			
		||||
					if (!(0 <= dest && dest < pt.code.length)) return 0;
 | 
			
		||||
					if (dest > 0) {
 | 
			
		||||
						/* cannot jump to a setlist count */
 | 
			
		||||
						int d = pt.code[dest - 1];
 | 
			
		||||
						if ((Lua.GET_OPCODE(d) == Lua.OP_SETLIST && Lua.GETARG_C(d) == 0)) return 0;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			}
 | 
			
		||||
			if (Lua.testAMode(op)) {
 | 
			
		||||
				if (a == reg)
 | 
			
		||||
					last = pc; /* change register `a' */
 | 
			
		||||
			}
 | 
			
		||||
			if (Lua.testTMode(op)) {
 | 
			
		||||
				if (!(pc + 2 < pt.code.length)) return 0; /* check skip */
 | 
			
		||||
				if (!(Lua.GET_OPCODE(pt.code[pc + 1]) == Lua.OP_JMP)) return 0;
 | 
			
		||||
			}
 | 
			
		||||
			switch (op) {
 | 
			
		||||
			case Lua.OP_LOADBOOL: {
 | 
			
		||||
				if (!(c == 0 || pc + 2 < pt.code.length)) return 0; /* check its jump */
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_LOADNIL: {
 | 
			
		||||
				if (a <= reg && reg <= b)
 | 
			
		||||
					last = pc; /* set registers from `a' to `b' */
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_GETUPVAL:
 | 
			
		||||
			case Lua.OP_SETUPVAL: {
 | 
			
		||||
				if (!(b < pt.nups)) return 0;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_GETGLOBAL:
 | 
			
		||||
			case Lua.OP_SETGLOBAL: {
 | 
			
		||||
				if (!(pt.k[b].isstring())) return 0;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_SELF: {
 | 
			
		||||
				if (!checkreg(pt, a + 1)) return 0;
 | 
			
		||||
				if (reg == a + 1)
 | 
			
		||||
					last = pc;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_CONCAT: {
 | 
			
		||||
				if (!(b < c)) return 0; /* at least two operands */
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_TFORLOOP: {
 | 
			
		||||
				if (!(c >= 1)) return 0; /* at least one result (control variable) */
 | 
			
		||||
				if (!checkreg(pt, a + 2 + c)) return 0; /* space for results */
 | 
			
		||||
				if (reg >= a + 2)
 | 
			
		||||
					last = pc; /* affect all regs above its base */
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_FORLOOP:
 | 
			
		||||
			case Lua.OP_FORPREP:
 | 
			
		||||
				if (!checkreg(pt, a + 3)) return 0;
 | 
			
		||||
				/* go through */
 | 
			
		||||
			case Lua.OP_JMP: {
 | 
			
		||||
				int dest = pc + 1 + b;
 | 
			
		||||
				/* not full check and jump is forward and do not skip `lastpc'? */
 | 
			
		||||
				if (reg != Lua.NO_REG && pc < dest && dest <= lastpc)
 | 
			
		||||
					pc += b; /* do the jump */
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_CALL:
 | 
			
		||||
			case Lua.OP_TAILCALL: {
 | 
			
		||||
				if (b != 0) {
 | 
			
		||||
					if (!checkreg(pt, a + b - 1)) return 0;
 | 
			
		||||
				}
 | 
			
		||||
				c--; /* c = num. returns */
 | 
			
		||||
				if (c == Lua.LUA_MULTRET) {
 | 
			
		||||
					if (!(checkopenop(pt, pc))) return 0;
 | 
			
		||||
				} else if (c != 0)
 | 
			
		||||
					if (!checkreg(pt, a + c - 1)) return 0;
 | 
			
		||||
				if (reg >= a)
 | 
			
		||||
					last = pc; /* affect all registers above base */
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_RETURN: {
 | 
			
		||||
				b--; /* b = num. returns */
 | 
			
		||||
				if (b > 0)
 | 
			
		||||
					if (!checkreg(pt, a + b - 1)) return 0;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_SETLIST: {
 | 
			
		||||
				if (b > 0)
 | 
			
		||||
					if (!checkreg(pt, a + b)) return 0;
 | 
			
		||||
				if (c == 0)
 | 
			
		||||
					pc++;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_CLOSURE: {
 | 
			
		||||
				int nup, j;
 | 
			
		||||
				if (!(b < pt.p.length)) return 0;
 | 
			
		||||
				nup = pt.p[b].nups;
 | 
			
		||||
				if (!(pc + nup < pt.code.length)) return 0;
 | 
			
		||||
				for (j = 1; j <= nup; j++) {
 | 
			
		||||
					int op1 = Lua.GET_OPCODE(pt.code[pc + j]);
 | 
			
		||||
					if (!(op1 == Lua.OP_GETUPVAL || op1 == Lua.OP_MOVE)) return 0;
 | 
			
		||||
				}
 | 
			
		||||
				if (reg != Lua.NO_REG) /* tracing? */
 | 
			
		||||
					pc += nup; /* do not 'execute' these pseudo-instructions */
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			case Lua.OP_VARARG: {
 | 
			
		||||
				if (!((pt.is_vararg & Lua.VARARG_ISVARARG) != 0
 | 
			
		||||
						&& (pt.is_vararg & Lua.VARARG_NEEDSARG) == 0)) return 0;
 | 
			
		||||
				b--;
 | 
			
		||||
				if (b == Lua.LUA_MULTRET)
 | 
			
		||||
					if (!(checkopenop(pt, pc))) return 0;
 | 
			
		||||
				if (!checkreg(pt, a + b - 1)) return 0;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return pt.code[last];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -1,607 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import java.io.ByteArrayOutputStream;
 | 
			
		||||
import java.io.EOFException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaString;
 | 
			
		||||
import org.luaj.vm2.LuaTable;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Abstract base class extending {@link LibFunction} which implements the 
 | 
			
		||||
 * core of the lua standard {@code io} library.   
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * It contains the implementation of the io library support that is common to
 | 
			
		||||
 * the JSE and JME platforms. 
 | 
			
		||||
 * In practice on of the concrete IOLib subclasses is chosen:  
 | 
			
		||||
 * {@link org.luaj.vm2.lib.jse.JseIoLib} for the JSE platform, and 
 | 
			
		||||
 * {@link org.luaj.vm2.lib.jme.JmeIoLib} for the JME platform.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The JSE implementation conforms almost completely to the C-based lua library, 
 | 
			
		||||
 * while the JME implementation follows closely except in the area of random-access files, 
 | 
			
		||||
 * which are difficult to support properly on JME. 
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * Typically, this library is included as part of a call to either 
 | 
			
		||||
 * {@link JsePlatform#standardGlobals()} or {@link JmePlatform#standardGlobals()}
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To instantiate and use it directly, 
 | 
			
		||||
 * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LuaTable _G = new LuaTable();
 | 
			
		||||
 * _G.load(new JseIoLib());
 | 
			
		||||
 * LuaThread.setGlobals(_G);
 | 
			
		||||
 * _G.load(new JseBaseLib());
 | 
			
		||||
 * _G.load(new PackageLib());
 | 
			
		||||
 * _G.load(new JseIoLib());
 | 
			
		||||
 * _G.get("io").get("write").call(LuaValue.valueOf("hello, world\n"));
 | 
			
		||||
 * } </pre>
 | 
			
		||||
 * Doing so will ensure the library is properly initialized 
 | 
			
		||||
 * and loaded into the globals table. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This has been implemented to match as closely as possible the behavior in the corresponding library in C.
 | 
			
		||||
 * @see LibFunction
 | 
			
		||||
 * @see JsePlatform
 | 
			
		||||
 * @see JmePlatform
 | 
			
		||||
 * @see JseIoLib
 | 
			
		||||
 * @see JmeIoLib
 | 
			
		||||
 * @see <a href="http://www.lua.org/manual/5.1/manual.html#5.7">http://www.lua.org/manual/5.1/manual.html#5.7</a>
 | 
			
		||||
 */
 | 
			
		||||
abstract 
 | 
			
		||||
public class IoLib extends OneArgFunction {
 | 
			
		||||
 | 
			
		||||
	abstract 
 | 
			
		||||
	protected class File extends LuaValue{
 | 
			
		||||
		abstract public void write( LuaString string ) throws IOException;
 | 
			
		||||
		abstract public void flush() throws IOException;
 | 
			
		||||
		abstract public boolean isstdfile();
 | 
			
		||||
		abstract public void close() throws IOException;
 | 
			
		||||
		abstract public boolean isclosed();
 | 
			
		||||
		// returns new position
 | 
			
		||||
		abstract public int seek(String option, int bytecount) throws IOException;
 | 
			
		||||
		abstract public void setvbuf(String mode, int size);		
 | 
			
		||||
		// get length remaining to read
 | 
			
		||||
		abstract public int remaining() throws IOException;		
 | 
			
		||||
		// peek ahead one character
 | 
			
		||||
		abstract public int peek() throws IOException, EOFException;		
 | 
			
		||||
		// return char if read, -1 if eof, throw IOException on other exception 
 | 
			
		||||
		abstract public int read() throws IOException, EOFException;
 | 
			
		||||
		// return number of bytes read if positive, false if eof, throw IOException on other exception
 | 
			
		||||
		abstract public int read(byte[] bytes, int offset, int length) throws IOException;
 | 
			
		||||
		
 | 
			
		||||
		// delegate method access to file methods table
 | 
			
		||||
		public LuaValue get( LuaValue key ) {
 | 
			
		||||
			return filemethods.get(key);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// essentially a userdata instance
 | 
			
		||||
		public int type() {
 | 
			
		||||
			return LuaValue.TUSERDATA;
 | 
			
		||||
		}
 | 
			
		||||
		public String typename() {
 | 
			
		||||
			return "userdata";
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// displays as "file" type
 | 
			
		||||
		public String tojstring() {
 | 
			
		||||
			return "file: " + Integer.toHexString(hashCode());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Wrap the standard input. 
 | 
			
		||||
	 * @return File 
 | 
			
		||||
	 * @throws IOException
 | 
			
		||||
	 */
 | 
			
		||||
	abstract protected File wrapStdin() throws IOException;
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Wrap the standard output. 
 | 
			
		||||
	 * @return File 
 | 
			
		||||
	 * @throws IOException
 | 
			
		||||
	 */
 | 
			
		||||
	abstract protected File wrapStdout() throws IOException;
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Open a file in a particular mode. 
 | 
			
		||||
	 * @param filename
 | 
			
		||||
	 * @param readMode true if opening in read mode
 | 
			
		||||
	 * @param appendMode true if opening in append mode
 | 
			
		||||
	 * @param updateMode true if opening in update mode
 | 
			
		||||
	 * @param binaryMode true if opening in binary mode
 | 
			
		||||
	 * @return File object if successful
 | 
			
		||||
	 * @throws IOException if could not be opened
 | 
			
		||||
	 */
 | 
			
		||||
	abstract protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Open a temporary file. 
 | 
			
		||||
	 * @return File object if successful
 | 
			
		||||
	 * @throws IOException if could not be opened
 | 
			
		||||
	 */
 | 
			
		||||
	abstract protected File tmpFile() throws IOException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Start a new process and return a file for input or output
 | 
			
		||||
	 * @param prog the program to execute
 | 
			
		||||
	 * @param mode "r" to read, "w" to write
 | 
			
		||||
	 * @return File to read to or write from 
 | 
			
		||||
	 * @throws IOException if an i/o exception occurs
 | 
			
		||||
	 */
 | 
			
		||||
	abstract protected File openProgram(String prog, String mode) throws IOException;
 | 
			
		||||
 | 
			
		||||
	private File infile  = null;
 | 
			
		||||
	private File outfile = null;
 | 
			
		||||
	private File errfile = null;
 | 
			
		||||
 | 
			
		||||
	private static final LuaValue STDIN       = valueOf("stdin");
 | 
			
		||||
	private static final LuaValue STDOUT      = valueOf("stdout");
 | 
			
		||||
	private static final LuaValue STDERR      = valueOf("stderr");		
 | 
			
		||||
	private static final LuaValue FILE        = valueOf("file");
 | 
			
		||||
	private static final LuaValue CLOSED_FILE = valueOf("closed file");
 | 
			
		||||
	
 | 
			
		||||
	private static final int IO_CLOSE      = 0;
 | 
			
		||||
	private static final int IO_FLUSH      = 1;
 | 
			
		||||
	private static final int IO_INPUT      = 2;
 | 
			
		||||
	private static final int IO_LINES      = 3;
 | 
			
		||||
	private static final int IO_OPEN       = 4;
 | 
			
		||||
	private static final int IO_OUTPUT     = 5;
 | 
			
		||||
	private static final int IO_POPEN      = 6;
 | 
			
		||||
	private static final int IO_READ       = 7;
 | 
			
		||||
	private static final int IO_TMPFILE    = 8;
 | 
			
		||||
	private static final int IO_TYPE       = 9;
 | 
			
		||||
	private static final int IO_WRITE      = 10;
 | 
			
		||||
 | 
			
		||||
	private static final int FILE_CLOSE    = 11;
 | 
			
		||||
	private static final int FILE_FLUSH    = 12;
 | 
			
		||||
	private static final int FILE_LINES    = 13;
 | 
			
		||||
	private static final int FILE_READ     = 14;
 | 
			
		||||
	private static final int FILE_SEEK     = 15;
 | 
			
		||||
	private static final int FILE_SETVBUF  = 16;
 | 
			
		||||
	private static final int FILE_WRITE    = 17;
 | 
			
		||||
	
 | 
			
		||||
	private static final int IO_INDEX      = 18;
 | 
			
		||||
	private static final int LINES_ITER    = 19;
 | 
			
		||||
 | 
			
		||||
	public static final String[] IO_NAMES = {
 | 
			
		||||
		"close",
 | 
			
		||||
		"flush",
 | 
			
		||||
		"input",
 | 
			
		||||
		"lines",
 | 
			
		||||
		"open",
 | 
			
		||||
		"output",
 | 
			
		||||
		"popen",
 | 
			
		||||
		"read",
 | 
			
		||||
		"tmpfile",
 | 
			
		||||
		"type",
 | 
			
		||||
		"write",
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
	public static final String[] FILE_NAMES = {
 | 
			
		||||
		"close",
 | 
			
		||||
		"flush",
 | 
			
		||||
		"lines",
 | 
			
		||||
		"read",
 | 
			
		||||
		"seek",
 | 
			
		||||
		"setvbuf",
 | 
			
		||||
		"write",
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	LuaTable filemethods;
 | 
			
		||||
	
 | 
			
		||||
	public IoLib() {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue call(LuaValue arg) {
 | 
			
		||||
		
 | 
			
		||||
		// io lib functions
 | 
			
		||||
		LuaTable t = new LuaTable();
 | 
			
		||||
		bind(t, IoLibV.class, IO_NAMES );
 | 
			
		||||
		
 | 
			
		||||
		// create file methods table
 | 
			
		||||
		filemethods = new LuaTable();
 | 
			
		||||
		bind(filemethods, IoLibV.class, FILE_NAMES, FILE_CLOSE );
 | 
			
		||||
 | 
			
		||||
		// set up file metatable
 | 
			
		||||
		LuaTable mt = new LuaTable();
 | 
			
		||||
		bind(mt, IoLibV.class, new String[] { "__index" }, IO_INDEX );
 | 
			
		||||
		t.setmetatable( mt );
 | 
			
		||||
		
 | 
			
		||||
		// all functions link to library instance
 | 
			
		||||
		setLibInstance( t );
 | 
			
		||||
		setLibInstance( filemethods );
 | 
			
		||||
		setLibInstance( mt );
 | 
			
		||||
		
 | 
			
		||||
		// return the table
 | 
			
		||||
		env.set("io", t);
 | 
			
		||||
		PackageLib.instance.LOADED.set("io", t);
 | 
			
		||||
		return t;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void setLibInstance(LuaTable t) {
 | 
			
		||||
		LuaValue[] k = t.keys();
 | 
			
		||||
		for ( int i=0, n=k.length; i<n; i++ )
 | 
			
		||||
			((IoLibV) t.get(k[i])).iolib = this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	static final class IoLibV extends VarArgFunction {
 | 
			
		||||
		public IoLib iolib;
 | 
			
		||||
		public IoLibV() {
 | 
			
		||||
		}
 | 
			
		||||
		public IoLibV(LuaValue env, String name, int opcode, IoLib iolib) {
 | 
			
		||||
			super();
 | 
			
		||||
			this.env = env;
 | 
			
		||||
			this.name = name;
 | 
			
		||||
			this.opcode = opcode;
 | 
			
		||||
			this.iolib = iolib;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Varargs invoke(Varargs args) {
 | 
			
		||||
			try {
 | 
			
		||||
				switch ( opcode ) {
 | 
			
		||||
				case IO_FLUSH:		return iolib._io_flush();
 | 
			
		||||
				case IO_TMPFILE:	return iolib._io_tmpfile();
 | 
			
		||||
				case IO_CLOSE:		return iolib._io_close(args.arg1());
 | 
			
		||||
				case IO_INPUT:		return iolib._io_input(args.arg1());
 | 
			
		||||
				case IO_OUTPUT:		return iolib._io_output(args.arg1());
 | 
			
		||||
				case IO_TYPE:		return iolib._io_type(args.arg1());
 | 
			
		||||
				case IO_POPEN:		return iolib._io_popen(args.checkjstring(1),args.optjstring(2,"r"));
 | 
			
		||||
				case IO_OPEN:		return iolib._io_open(args.checkjstring(1), args.optjstring(2,"r"));
 | 
			
		||||
				case IO_LINES:		return iolib._io_lines(args.isvalue(1)? args.checkjstring(1): null);
 | 
			
		||||
				case IO_READ:		return iolib._io_read(args);
 | 
			
		||||
				case IO_WRITE:		return iolib._io_write(args);
 | 
			
		||||
					
 | 
			
		||||
				case FILE_CLOSE:	return iolib._file_close(args.arg1());
 | 
			
		||||
				case FILE_FLUSH:	return iolib._file_flush(args.arg1());
 | 
			
		||||
				case FILE_SETVBUF:	return iolib._file_setvbuf(args.arg1(),args.checkjstring(2),args.optint(3,1024));
 | 
			
		||||
				case FILE_LINES:	return iolib._file_lines(args.arg1());
 | 
			
		||||
				case FILE_READ:		return iolib._file_read(args.arg1(),args.subargs(2));
 | 
			
		||||
				case FILE_SEEK:		return iolib._file_seek(args.arg1(),args.optjstring(2,"cur"),args.optint(3,0));
 | 
			
		||||
				case FILE_WRITE:	return iolib._file_write(args.arg1(),args.subargs(2));
 | 
			
		||||
 | 
			
		||||
				case IO_INDEX:		return iolib._io_index(args.arg(2));
 | 
			
		||||
				case LINES_ITER:	return iolib._lines_iter(env);
 | 
			
		||||
				}
 | 
			
		||||
			} catch ( IOException ioe ) {
 | 
			
		||||
				return errorresult(ioe);
 | 
			
		||||
			}
 | 
			
		||||
			return NONE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private File input() {
 | 
			
		||||
		return infile!=null? infile: (infile=ioopenfile("-","r"));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	//	io.flush() -> bool 
 | 
			
		||||
	public Varargs _io_flush() throws IOException {
 | 
			
		||||
		checkopen(output());
 | 
			
		||||
		outfile.flush();
 | 
			
		||||
		return LuaValue.TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//	io.tmpfile() -> file
 | 
			
		||||
	public Varargs _io_tmpfile() throws IOException {
 | 
			
		||||
		return tmpFile();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//	io.close([file]) -> void
 | 
			
		||||
	public Varargs _io_close(LuaValue file) throws IOException {
 | 
			
		||||
		File f = file.isnil()? output(): checkfile(file);
 | 
			
		||||
		checkopen(f);
 | 
			
		||||
		return ioclose(f);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//	io.input([file]) -> file
 | 
			
		||||
	public Varargs _io_input(LuaValue file) {
 | 
			
		||||
		infile = file.isnil()? input(): 
 | 
			
		||||
				file.isstring()? ioopenfile(file.checkjstring(),"r"):
 | 
			
		||||
				checkfile(file);
 | 
			
		||||
		return infile;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// io.output(filename) -> file
 | 
			
		||||
	public Varargs _io_output(LuaValue filename) {
 | 
			
		||||
		outfile = filename.isnil()? output(): 
 | 
			
		||||
				  filename.isstring()? ioopenfile(filename.checkjstring(),"w"):
 | 
			
		||||
				  checkfile(filename);
 | 
			
		||||
		return outfile;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//	io.type(obj) -> "file" | "closed file" | nil
 | 
			
		||||
	public Varargs _io_type(LuaValue obj) {
 | 
			
		||||
		File f = optfile(obj);
 | 
			
		||||
		return f!=null?
 | 
			
		||||
			f.isclosed()? CLOSED_FILE: FILE:
 | 
			
		||||
			NIL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// io.popen(prog, [mode]) -> file
 | 
			
		||||
	public Varargs _io_popen(String prog, String mode) throws IOException {
 | 
			
		||||
		return openProgram(prog, mode);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//	io.open(filename, [mode]) -> file | nil,err
 | 
			
		||||
	public Varargs _io_open(String filename, String mode) throws IOException {
 | 
			
		||||
		return rawopenfile(filename, mode);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//	io.lines(filename) -> iterator
 | 
			
		||||
	public Varargs _io_lines(String filename) {
 | 
			
		||||
		infile = filename==null? input(): ioopenfile(filename,"r");
 | 
			
		||||
		checkopen(infile);
 | 
			
		||||
		return lines(infile);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//	io.read(...) -> (...)
 | 
			
		||||
	public Varargs _io_read(Varargs args) throws IOException {
 | 
			
		||||
		checkopen(input());
 | 
			
		||||
		return ioread(infile,args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//	io.write(...) -> void
 | 
			
		||||
	public Varargs _io_write(Varargs args) throws IOException {
 | 
			
		||||
		checkopen(output());
 | 
			
		||||
		return iowrite(outfile,args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// file:close() -> void
 | 
			
		||||
	public Varargs _file_close(LuaValue file) throws IOException {
 | 
			
		||||
		return ioclose(checkfile(file));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// file:flush() -> void
 | 
			
		||||
	public Varargs _file_flush(LuaValue file) throws IOException {
 | 
			
		||||
		checkfile(file).flush();
 | 
			
		||||
		return LuaValue.TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// file:setvbuf(mode,[size]) -> void
 | 
			
		||||
	public Varargs _file_setvbuf(LuaValue file, String mode, int size) {
 | 
			
		||||
		checkfile(file).setvbuf(mode,size);
 | 
			
		||||
		return LuaValue.TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// file:lines() -> iterator
 | 
			
		||||
	public Varargs _file_lines(LuaValue file) {
 | 
			
		||||
		return lines(checkfile(file));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//	file:read(...) -> (...)
 | 
			
		||||
	public Varargs _file_read(LuaValue file, Varargs subargs) throws IOException {
 | 
			
		||||
		return ioread(checkfile(file),subargs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//  file:seek([whence][,offset]) -> pos | nil,error
 | 
			
		||||
	public Varargs _file_seek(LuaValue file, String whence, int offset) throws IOException {
 | 
			
		||||
		return valueOf( checkfile(file).seek(whence,offset) );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//	file:write(...) -> void		
 | 
			
		||||
	public Varargs _file_write(LuaValue file, Varargs subargs) throws IOException {
 | 
			
		||||
		return iowrite(checkfile(file),subargs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// __index, returns a field
 | 
			
		||||
	public Varargs _io_index(LuaValue v) {
 | 
			
		||||
		return v.equals(STDOUT)?output():
 | 
			
		||||
			   v.equals(STDIN)?  input():
 | 
			
		||||
			   v.equals(STDERR)? errput(): NIL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//	lines iterator(s,var) -> var'
 | 
			
		||||
	public Varargs _lines_iter(LuaValue file) throws IOException {
 | 
			
		||||
		return freadline(checkfile(file));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private File output() {
 | 
			
		||||
		return outfile!=null? outfile: (outfile=ioopenfile("-","w"));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private File errput() {
 | 
			
		||||
		return errfile!=null? errfile: (errfile=ioopenfile("-","w"));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private File ioopenfile(String filename, String mode) {
 | 
			
		||||
		try {
 | 
			
		||||
			return rawopenfile(filename, mode);
 | 
			
		||||
		} catch ( Exception e ) {
 | 
			
		||||
			error("io error: "+e.getMessage());
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static Varargs ioclose(File f) throws IOException {
 | 
			
		||||
		if ( f.isstdfile() )
 | 
			
		||||
			return errorresult("cannot close standard file");
 | 
			
		||||
		else {
 | 
			
		||||
			f.close();
 | 
			
		||||
			return successresult();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static Varargs successresult() {
 | 
			
		||||
		return LuaValue.TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static Varargs errorresult(Exception ioe) {
 | 
			
		||||
		String s = ioe.getMessage();		
 | 
			
		||||
		return errorresult("io error: "+(s!=null? s: ioe.toString()));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private static Varargs errorresult(String errortext) {
 | 
			
		||||
		return varargsOf(NIL, valueOf(errortext));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private Varargs lines(final File f) {
 | 
			
		||||
		try {
 | 
			
		||||
			return new IoLibV(f,"lnext",LINES_ITER,this);
 | 
			
		||||
		} catch ( Exception e ) {
 | 
			
		||||
			return error("lines: "+e);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static Varargs iowrite(File f, Varargs args) throws IOException {
 | 
			
		||||
		for ( int i=1, n=args.narg(); i<=n; i++ )
 | 
			
		||||
			f.write( args.checkstring(i) );
 | 
			
		||||
		return LuaValue.TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private Varargs ioread(File f, Varargs args) throws IOException {
 | 
			
		||||
		int i,n=args.narg();
 | 
			
		||||
		LuaValue[] v = new LuaValue[n];
 | 
			
		||||
		LuaValue ai,vi;
 | 
			
		||||
		LuaString fmt;
 | 
			
		||||
		for ( i=0; i<n; ) {
 | 
			
		||||
			item: switch ( (ai = args.arg(i+1)).type() ) {
 | 
			
		||||
				case LuaValue.TNUMBER:
 | 
			
		||||
					vi = freadbytes(f,ai.toint());
 | 
			
		||||
					break item;
 | 
			
		||||
				case LuaValue.TSTRING:
 | 
			
		||||
					fmt = ai.checkstring();
 | 
			
		||||
					if ( fmt.m_length == 2 && fmt.m_bytes[fmt.m_offset] == '*' ) {
 | 
			
		||||
						switch ( fmt.m_bytes[fmt.m_offset+1] ) {
 | 
			
		||||
						case 'n': vi = freadnumber(f); break item;
 | 
			
		||||
						case 'l': vi = freadline(f); break item;
 | 
			
		||||
						case 'a': vi = freadall(f); break item;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				default: 
 | 
			
		||||
					return argerror( i+1, "(invalid format)" ); 
 | 
			
		||||
			}
 | 
			
		||||
			if ( (v[i++] = vi).isnil() )
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		return i==0? NIL: varargsOf(v, 0, i);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static File checkfile(LuaValue val) {
 | 
			
		||||
		File f = optfile(val);
 | 
			
		||||
		if ( f == null )
 | 
			
		||||
			argerror(1,"file");
 | 
			
		||||
		checkopen( f );
 | 
			
		||||
		return f;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private static File optfile(LuaValue val) {
 | 
			
		||||
		return (val instanceof File)? (File) val: null;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private static File checkopen(File file) {
 | 
			
		||||
		if ( file.isclosed() )
 | 
			
		||||
			error("attempt to use a closed file");
 | 
			
		||||
		return file;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private File rawopenfile(String filename, String mode) throws IOException {
 | 
			
		||||
		boolean isstdfile = "-".equals(filename);
 | 
			
		||||
		boolean isreadmode = mode.startsWith("r");
 | 
			
		||||
		if ( isstdfile ) {
 | 
			
		||||
			return isreadmode? 
 | 
			
		||||
				wrapStdin():
 | 
			
		||||
				wrapStdout();
 | 
			
		||||
		}
 | 
			
		||||
		boolean isappend = mode.startsWith("a");
 | 
			
		||||
		boolean isupdate = mode.indexOf("+") > 0;
 | 
			
		||||
		boolean isbinary = mode.endsWith("b");
 | 
			
		||||
		return openFile( filename, isreadmode, isappend, isupdate, isbinary );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// ------------- file reading utilitied ------------------
 | 
			
		||||
	
 | 
			
		||||
	public static LuaValue freadbytes(File f, int count) throws IOException {
 | 
			
		||||
		byte[] b = new byte[count];
 | 
			
		||||
		int r;
 | 
			
		||||
		if ( ( r = f.read(b,0,b.length) ) < 0 )
 | 
			
		||||
			return NIL;
 | 
			
		||||
		return LuaString.valueOf(b, 0, r);
 | 
			
		||||
	}
 | 
			
		||||
	public static LuaValue freaduntil(File f,boolean lineonly) throws IOException {
 | 
			
		||||
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
 | 
			
		||||
		int c;
 | 
			
		||||
		try {
 | 
			
		||||
			if ( lineonly ) {
 | 
			
		||||
				loop: while ( (c = f.read()) > 0 ) { 
 | 
			
		||||
					switch ( c ) {
 | 
			
		||||
					case '\r': break;
 | 
			
		||||
					case '\n': break loop;
 | 
			
		||||
					default: baos.write(c); break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				while ( (c = f.read()) > 0 ) 
 | 
			
		||||
					baos.write(c);
 | 
			
		||||
			}
 | 
			
		||||
		} catch ( EOFException e ) {
 | 
			
		||||
			c = -1;
 | 
			
		||||
		}
 | 
			
		||||
		return ( c < 0 && baos.size() == 0 )? 
 | 
			
		||||
			(LuaValue) NIL:
 | 
			
		||||
			(LuaValue) LuaString.valueOf(baos.toByteArray());
 | 
			
		||||
	}
 | 
			
		||||
	public static LuaValue freadline(File f) throws IOException {
 | 
			
		||||
		return freaduntil(f,true);
 | 
			
		||||
	}
 | 
			
		||||
	public static LuaValue freadall(File f) throws IOException {
 | 
			
		||||
		int n = f.remaining();
 | 
			
		||||
		if ( n >= 0 ) {
 | 
			
		||||
			return freadbytes(f, n);
 | 
			
		||||
		} else {
 | 
			
		||||
			return freaduntil(f,false);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	public static LuaValue freadnumber(File f) throws IOException {
 | 
			
		||||
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
 | 
			
		||||
		freadchars(f," \t\r\n",null);
 | 
			
		||||
		freadchars(f,"-+",baos);
 | 
			
		||||
		//freadchars(f,"0",baos);
 | 
			
		||||
		//freadchars(f,"xX",baos);
 | 
			
		||||
		freadchars(f,"0123456789",baos);
 | 
			
		||||
		freadchars(f,".",baos);
 | 
			
		||||
		freadchars(f,"0123456789",baos);
 | 
			
		||||
		//freadchars(f,"eEfFgG",baos);
 | 
			
		||||
		// freadchars(f,"+-",baos);
 | 
			
		||||
		//freadchars(f,"0123456789",baos);
 | 
			
		||||
		String s = baos.toString();
 | 
			
		||||
		return s.length()>0? valueOf( Double.parseDouble(s) ): NIL;
 | 
			
		||||
	}
 | 
			
		||||
	private static void freadchars(File f, String chars, ByteArrayOutputStream baos) throws IOException {
 | 
			
		||||
		int c;
 | 
			
		||||
		while ( true ) {
 | 
			
		||||
			c = f.peek();
 | 
			
		||||
			if ( chars.indexOf(c) < 0 ) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			f.read();
 | 
			
		||||
			if ( baos != null )
 | 
			
		||||
				baos.write( c );
 | 
			
		||||
		}
 | 
			
		||||
	}		
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@@ -1,200 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaError;
 | 
			
		||||
import org.luaj.vm2.LuaFunction;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Subclass of {@link LuaFunction} common to Java functions exposed to lua. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To provide for common implementations in JME and JSE, 
 | 
			
		||||
 * library functions are typically grouped on one or more library classes
 | 
			
		||||
 * and an opcode per library function is defined and used to key the switch
 | 
			
		||||
 * to the correct function within the library.  
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Since lua functions can be called with too few or too many arguments, 
 | 
			
		||||
 * and there are overloaded {@link LuaValue#call()} functions with varying 
 | 
			
		||||
 * number of arguments, a Java function exposed in lua needs to handle  the
 | 
			
		||||
 * argument fixup when a function is called with a number of arguments 
 | 
			
		||||
 * differs from that expected.  
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To simplify the creation of library functions, 
 | 
			
		||||
 * there are 5 direct subclasses to handle common cases based on number of 
 | 
			
		||||
 * argument values and number of return return values.
 | 
			
		||||
 * <ul>
 | 
			
		||||
 * <li>{@link ZeroArgFunction}</li>
 | 
			
		||||
 * <li>{@link OneArgFunction}</li>
 | 
			
		||||
 * <li>{@link TwoArgFunction}</li>
 | 
			
		||||
 * <li>{@link ThreeArgFunction}</li>
 | 
			
		||||
 * <li>{@link VarArgFunction}</li>
 | 
			
		||||
 * </ul>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To be a Java library that can be loaded via {@code require}, it should have 
 | 
			
		||||
 * a public constructor that returns a {@link LuaValue} that, when executed, 
 | 
			
		||||
 * initializes the library. 
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * For example, the following code will implement a library called "hyperbolic" 
 | 
			
		||||
 * with two functions, "sinh", and "cosh":
 | 
			
		||||
 <pre> {@code 
 | 
			
		||||
 * import org.luaj.vm2.LuaValue;
 | 
			
		||||
 * import org.luaj.vm2.lib.OneArgFunction;
 | 
			
		||||
 * 
 | 
			
		||||
 * public class hyperbolic extends OneArgFunction {
 | 
			
		||||
 *
 | 
			
		||||
 *	public hyperbolic() {}
 | 
			
		||||
 *
 | 
			
		||||
 *	public LuaValue call(LuaValue libname) {
 | 
			
		||||
 *		LuaValue library = tableOf();
 | 
			
		||||
 *		library.set( "sinh", new sinh() );
 | 
			
		||||
 *		library.set( "cosh", new cosh() );
 | 
			
		||||
 *		env.set( "hyperbolic", library );
 | 
			
		||||
 *		return library;
 | 
			
		||||
 *	}
 | 
			
		||||
 *
 | 
			
		||||
 *	static class sinh extends OneArgFunction {
 | 
			
		||||
 *		public LuaValue call(LuaValue x) {
 | 
			
		||||
 *			return LuaValue.valueOf(Math.sinh(x.checkdouble()));
 | 
			
		||||
 *		}
 | 
			
		||||
 *	}
 | 
			
		||||
 *	
 | 
			
		||||
 *	static class cosh extends OneArgFunction {
 | 
			
		||||
 *		public LuaValue call(LuaValue x) {
 | 
			
		||||
 *			return LuaValue.valueOf(Math.cosh(x.checkdouble()));
 | 
			
		||||
 *		}
 | 
			
		||||
 *	}
 | 
			
		||||
 *}
 | 
			
		||||
 *}</pre>
 | 
			
		||||
 * The default constructor is used to instantiate the library 
 | 
			
		||||
 * in response to {@code require 'hyperbolic'} statement,
 | 
			
		||||
 * provided it is on Javas class path. 
 | 
			
		||||
 * This instance is then invoked with the name supplied to require() 
 | 
			
		||||
 * as the only argument, and library should initialized whatever global
 | 
			
		||||
 * data it needs to and place it into the environment if needed.
 | 
			
		||||
 * In this case, it creates two function, 'sinh', and 'cosh', and puts 
 | 
			
		||||
 * them into a global table called 'hyperbolic.'
 | 
			
		||||
 * It placed the library table into the globals via the {@link #env} 
 | 
			
		||||
 * local variable which corresponds to the globals that apply when the
 | 
			
		||||
 * library is loaded.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To test it, a script such as this can be used:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * local t = require('hyperbolic')
 | 
			
		||||
 * print( 't', t )
 | 
			
		||||
 * print( 'hyperbolic', hyperbolic )
 | 
			
		||||
 * for k,v in pairs(t) do
 | 
			
		||||
 * 	print( 'k,v', k,v )
 | 
			
		||||
 * end
 | 
			
		||||
 * print( 'sinh(.5)', hyperbolic.sinh(.5) )
 | 
			
		||||
 * print( 'cosh(.5)', hyperbolic.cosh(.5) )
 | 
			
		||||
 * }</pre> 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * It should produce something like:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * t	table: 3dbbd23f
 | 
			
		||||
 * hyperbolic	table: 3dbbd23f
 | 
			
		||||
 * k,v	cosh	function: 3dbbd128
 | 
			
		||||
 * k,v	sinh	function: 3dbbd242
 | 
			
		||||
 * sinh(.5)	0.5210953
 | 
			
		||||
 * cosh(.5)	1.127626
 | 
			
		||||
 * }</pre> 
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * See the source code in any of the library functions 
 | 
			
		||||
 * such as {@link BaseLib} or {@link TableLib} for other examples.  
 | 
			
		||||
 */
 | 
			
		||||
abstract public class LibFunction extends LuaFunction {
 | 
			
		||||
	
 | 
			
		||||
	/** User-defined opcode to differentiate between instances of the library function class. 
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Subclass will typicall switch on this value to provide the specific behavior for each function. 
 | 
			
		||||
	 */
 | 
			
		||||
	protected int opcode;
 | 
			
		||||
	
 | 
			
		||||
	/** The common name for this function, useful for debugging.
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Binding functions initialize this to the name to which it is bound.
 | 
			
		||||
	 */
 | 
			
		||||
	protected String name;
 | 
			
		||||
	
 | 
			
		||||
	/** Default constructor for use by subclasses */
 | 
			
		||||
	protected LibFunction() {		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public String tojstring() {
 | 
			
		||||
		return name != null? name: super.tojstring();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Bind a set of library functions.  
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * An array of names is provided, and the first name is bound 
 | 
			
		||||
	 * with opcode = 0, second with 1, etc. 
 | 
			
		||||
	 * @param env The environment to apply to each bound function 
 | 
			
		||||
	 * @param factory the Class to instantiate for each bound function
 | 
			
		||||
	 * @param names array of String names, one for each function.
 | 
			
		||||
	 * @see #bind(LuaValue, Class, String[], int)  
 | 
			
		||||
	 */
 | 
			
		||||
	protected void bind(LuaValue env, Class factory,  String[] names ) {
 | 
			
		||||
		bind( env, factory, names, 0 );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Bind a set of library functions, with an offset  
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * An array of names is provided, and the first name is bound 
 | 
			
		||||
	 * with opcode = {@code firstopcode}, second with {@code firstopcode+1}, etc. 
 | 
			
		||||
	 * @param env The environment to apply to each bound function 
 | 
			
		||||
	 * @param factory the Class to instantiate for each bound function
 | 
			
		||||
	 * @param names array of String names, one for each function.
 | 
			
		||||
	 * @param firstopcode the first opcode to use  
 | 
			
		||||
	 * @see #bind(LuaValue, Class, String[])  
 | 
			
		||||
	 */
 | 
			
		||||
	protected void bind(LuaValue env, Class factory,  String[] names, int firstopcode ) {
 | 
			
		||||
		try {
 | 
			
		||||
			for ( int i=0, n=names.length; i<n; i++ ) {
 | 
			
		||||
				LibFunction f = (LibFunction) factory.newInstance();
 | 
			
		||||
				f.opcode = firstopcode + i;
 | 
			
		||||
				f.name = names[i];
 | 
			
		||||
				f.env = env;
 | 
			
		||||
				env.set(f.name, f);
 | 
			
		||||
			}
 | 
			
		||||
		} catch ( Exception e ) {
 | 
			
		||||
			throw new LuaError( "bind failed: "+e );
 | 
			
		||||
		}
 | 
			
		||||
	}	
 | 
			
		||||
 | 
			
		||||
	/** Java code generation utility to allocate storage for upvalue, leave it empty */
 | 
			
		||||
	protected static LuaValue[] newupe() {
 | 
			
		||||
		return new LuaValue[1];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Java code generation utility to allocate storage for upvalue, initialize with nil */
 | 
			
		||||
	protected static LuaValue[] newupn() {
 | 
			
		||||
		return new LuaValue[] { NIL };
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Java code generation utility to allocate storage for upvalue, initialize with value */
 | 
			
		||||
	protected static LuaValue[] newupl(LuaValue v) {
 | 
			
		||||
		return new LuaValue[] { v };
 | 
			
		||||
	}
 | 
			
		||||
} 
 | 
			
		||||
@@ -1,251 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaDouble;
 | 
			
		||||
import org.luaj.vm2.LuaTable;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Subclass of {@link LibFunction} which implements the lua standard {@code math} 
 | 
			
		||||
 * library. 
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * It contains only the math library support that is possible on JME.  
 | 
			
		||||
 * For a more complete implementation based on math functions specific to JSE 
 | 
			
		||||
 * use {@link org.luaj.vm2.lib.jse.JseMathLib}. 
 | 
			
		||||
 * In Particular the following math functions are <b>not</b> implemented by this library:
 | 
			
		||||
 * <ul>
 | 
			
		||||
 * <li>acos</li>
 | 
			
		||||
 * <li>asin</li>
 | 
			
		||||
 * <li>atan</li>
 | 
			
		||||
 * <li>cosh</li>
 | 
			
		||||
 * <li>log</li>
 | 
			
		||||
 * <li>log10</li>
 | 
			
		||||
 * <li>sinh</li>
 | 
			
		||||
 * <li>tanh</li>
 | 
			
		||||
 * <li>atan2</li>
 | 
			
		||||
 * </ul>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The implementations of {@code exp()} and {@code pow()} are constructed by 
 | 
			
		||||
 * hand for JME, so will be slower and less accurate than when executed on the JSE platform.
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * Typically, this library is included as part of a call to either 
 | 
			
		||||
 * {@link JmePlatform#standardGlobals()}
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To instantiate and use it directly, 
 | 
			
		||||
 * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LuaTable _G = new LuaTable();
 | 
			
		||||
 * LuaThread.setGlobals(_G);
 | 
			
		||||
 * _G.load(new BaseLib());
 | 
			
		||||
 * _G.load(new PackageLib());
 | 
			
		||||
 * _G.load(new MathLib());
 | 
			
		||||
 * System.out.println( _G.get("math").get("sqrt").call( LuaValue.valueOf(2) ) );
 | 
			
		||||
 * } </pre>
 | 
			
		||||
 * Doing so will ensure the library is properly initialized 
 | 
			
		||||
 * and loaded into the globals table. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This has been implemented to match as closely as possible the behavior in the corresponding library in C.
 | 
			
		||||
 * @see LibFunction
 | 
			
		||||
 * @see JsePlatform
 | 
			
		||||
 * @see JmePlatform
 | 
			
		||||
 * @see JseMathLib
 | 
			
		||||
 * @see <a href="http://www.lua.org/manual/5.1/manual.html#5.6">http://www.lua.org/manual/5.1/manual.html#5.6</a>
 | 
			
		||||
 */
 | 
			
		||||
public class MathLib extends OneArgFunction {
 | 
			
		||||
	
 | 
			
		||||
	public static MathLib MATHLIB = null;
 | 
			
		||||
 | 
			
		||||
	private Random random;
 | 
			
		||||
	
 | 
			
		||||
	public MathLib() {
 | 
			
		||||
		MATHLIB = this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue call(LuaValue arg) {
 | 
			
		||||
		LuaTable t = new LuaTable(0,30);
 | 
			
		||||
		t.set( "pi", Math.PI );
 | 
			
		||||
		t.set( "huge", LuaDouble.POSINF );
 | 
			
		||||
		bind( t, MathLib1.class, new String[] {
 | 
			
		||||
			"abs", "ceil", "cos", "deg", 
 | 
			
		||||
			"exp", "floor", "rad", "sin", 
 | 
			
		||||
			"sqrt", "tan" } );
 | 
			
		||||
		bind( t, MathLib2.class, new String[] {
 | 
			
		||||
			"fmod", "ldexp", "pow", } );
 | 
			
		||||
		bind( t, MathLibV.class, new String[] {
 | 
			
		||||
			"frexp", "max", "min", "modf", 
 | 
			
		||||
			"randomseed", "random", } );
 | 
			
		||||
		((MathLibV) t.get("randomseed")).mathlib = this;
 | 
			
		||||
		((MathLibV) t.get("random"    )).mathlib = this;
 | 
			
		||||
		env.set("math", t);
 | 
			
		||||
		PackageLib.instance.LOADED.set("math", t);
 | 
			
		||||
		return t;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static final class MathLib1 extends OneArgFunction {
 | 
			
		||||
		public LuaValue call(LuaValue arg) {
 | 
			
		||||
			switch ( opcode ) {
 | 
			
		||||
			case 0: return valueOf(Math.abs(arg.checkdouble())); 
 | 
			
		||||
			case 1: return valueOf(Math.ceil(arg.checkdouble())); 
 | 
			
		||||
			case 2: return valueOf(Math.cos(arg.checkdouble())); 
 | 
			
		||||
			case 3: return valueOf(Math.toDegrees(arg.checkdouble())); 
 | 
			
		||||
			case 4: return dpow(Math.E,arg.checkdouble());
 | 
			
		||||
			case 5: return valueOf(Math.floor(arg.checkdouble()));
 | 
			
		||||
			case 6: return valueOf(Math.toRadians(arg.checkdouble())); 
 | 
			
		||||
			case 7: return valueOf(Math.sin(arg.checkdouble())); 
 | 
			
		||||
			case 8: return valueOf(Math.sqrt(arg.checkdouble())); 
 | 
			
		||||
			case 9: return valueOf(Math.tan(arg.checkdouble())); 
 | 
			
		||||
			}
 | 
			
		||||
			return NIL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	static final class MathLib2 extends TwoArgFunction {
 | 
			
		||||
		protected MathLib mathlib;
 | 
			
		||||
		public LuaValue call(LuaValue arg1, LuaValue arg2) {
 | 
			
		||||
			switch ( opcode ) {
 | 
			
		||||
			case 0: { // fmod
 | 
			
		||||
				double x = arg1.checkdouble();
 | 
			
		||||
				double y = arg2.checkdouble();
 | 
			
		||||
				double q = x/y;
 | 
			
		||||
				double f = x - y * (q>=0? Math.floor(q): Math.ceil(q));
 | 
			
		||||
				return valueOf( f );
 | 
			
		||||
			}
 | 
			
		||||
			case 1: { // ldexp
 | 
			
		||||
				double x = arg1.checkdouble();
 | 
			
		||||
				double y = arg2.checkdouble()+1023.5;
 | 
			
		||||
				long e = (long) ((0!=(1&((int)y)))? Math.floor(y): Math.ceil(y-1));
 | 
			
		||||
				return valueOf(x * Double.longBitsToDouble(e << 52));
 | 
			
		||||
			}
 | 
			
		||||
			case 2: { // pow
 | 
			
		||||
				return dpow(arg1.checkdouble(), arg2.checkdouble());
 | 
			
		||||
			}
 | 
			
		||||
			}
 | 
			
		||||
			return NIL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** compute power using installed math library, or default if there is no math library installed */
 | 
			
		||||
	public static LuaValue dpow(double a, double b) {
 | 
			
		||||
		return LuaDouble.valueOf( 
 | 
			
		||||
				MATHLIB!=null?
 | 
			
		||||
				MATHLIB.dpow_lib(a,b):
 | 
			
		||||
				dpow_default(a,b) );
 | 
			
		||||
	}
 | 
			
		||||
	public static double dpow_d(double a, double b) {
 | 
			
		||||
		return MATHLIB!=null? 
 | 
			
		||||
				MATHLIB.dpow_lib(a,b): 
 | 
			
		||||
				dpow_default(a,b);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Hook to override default dpow behavior with faster implementation.  
 | 
			
		||||
	 */
 | 
			
		||||
	public double dpow_lib(double a, double b) {
 | 
			
		||||
		return dpow_default(a,b);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Default JME version computes using longhand heuristics. 
 | 
			
		||||
	 */
 | 
			
		||||
	protected static double dpow_default(double a, double b) {
 | 
			
		||||
		if ( b < 0 )
 | 
			
		||||
			return 1 / dpow_default( a, -b );
 | 
			
		||||
		double p = 1;
 | 
			
		||||
		int whole = (int) b;
 | 
			
		||||
		for ( double v=a; whole > 0; whole>>=1, v*=v )
 | 
			
		||||
			if ( (whole & 1) != 0 )
 | 
			
		||||
				p *= v;
 | 
			
		||||
		if ( (b -= whole) > 0 ) {
 | 
			
		||||
			int frac = (int) (0x10000 * b);
 | 
			
		||||
			for ( ; (frac&0xffff)!=0; frac<<=1 ) {
 | 
			
		||||
				a = Math.sqrt(a);
 | 
			
		||||
				if ( (frac & 0x8000) != 0 )
 | 
			
		||||
					p *= a;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return p;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static final class MathLibV extends VarArgFunction {
 | 
			
		||||
		protected MathLib mathlib;
 | 
			
		||||
		public Varargs invoke(Varargs args) {
 | 
			
		||||
			switch ( opcode ) {
 | 
			
		||||
			case 0: { // frexp
 | 
			
		||||
				double x = args.checkdouble(1);
 | 
			
		||||
				if ( x == 0 ) return varargsOf(ZERO,ZERO);
 | 
			
		||||
				long bits = Double.doubleToLongBits( x );
 | 
			
		||||
				double m = ((bits & (~(-1L<<52))) + (1L<<52)) * ((bits >= 0)? (.5 / (1L<<52)): (-.5 / (1L<<52)));
 | 
			
		||||
				double e = (((int) (bits >> 52)) & 0x7ff) - 1022;
 | 
			
		||||
				return varargsOf( valueOf(m), valueOf(e) );
 | 
			
		||||
			}
 | 
			
		||||
			case 1: { // max
 | 
			
		||||
				double m = args.checkdouble(1);
 | 
			
		||||
				for ( int i=2,n=args.narg(); i<=n; ++i )
 | 
			
		||||
					m = Math.max(m,args.checkdouble(i));
 | 
			
		||||
				return valueOf(m);
 | 
			
		||||
			}
 | 
			
		||||
			case 2: { // min
 | 
			
		||||
				double m = args.checkdouble(1);
 | 
			
		||||
				for ( int i=2,n=args.narg(); i<=n; ++i )
 | 
			
		||||
					m = Math.min(m,args.checkdouble(i));
 | 
			
		||||
				return valueOf(m);
 | 
			
		||||
			}
 | 
			
		||||
			case 3: { // modf
 | 
			
		||||
				double x = args.checkdouble(1);
 | 
			
		||||
				double intPart = ( x > 0 ) ? Math.floor( x ) : Math.ceil( x );
 | 
			
		||||
				double fracPart = x - intPart;
 | 
			
		||||
				return varargsOf( valueOf(intPart), valueOf(fracPart) );
 | 
			
		||||
			}
 | 
			
		||||
			case 4: { // randomseed 
 | 
			
		||||
				long seed = args.checklong(1);
 | 
			
		||||
				mathlib.random = new Random(seed);
 | 
			
		||||
				return NONE;
 | 
			
		||||
			}
 | 
			
		||||
			case 5: { // random
 | 
			
		||||
				if ( mathlib.random == null )
 | 
			
		||||
					mathlib.random = new Random();
 | 
			
		||||
				
 | 
			
		||||
				switch ( args.narg() ) {
 | 
			
		||||
				case 0:
 | 
			
		||||
					return valueOf( mathlib.random.nextDouble() );
 | 
			
		||||
				case 1: {
 | 
			
		||||
					int m = args.checkint(1);
 | 
			
		||||
					if (m<1) argerror(1, "interval is empty");
 | 
			
		||||
					return valueOf( 1 + mathlib.random.nextInt(m) );
 | 
			
		||||
				}
 | 
			
		||||
				default: {
 | 
			
		||||
					int m = args.checkint(1);
 | 
			
		||||
					int n = args.checkint(2);
 | 
			
		||||
					if (n<m) argerror(2, "interval is empty");
 | 
			
		||||
					return valueOf( m + mathlib.random.nextInt(n+1-m) );
 | 
			
		||||
				}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			}
 | 
			
		||||
			return NONE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,79 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
 | 
			
		||||
/** Abstract base class for Java function implementations that take one argument and 
 | 
			
		||||
 * return one value. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Subclasses need only implement {@link LuaValue#call(LuaValue)} to complete this class, 
 | 
			
		||||
 * simplifying development.  
 | 
			
		||||
 * All other uses of {@link #call()}, {@link #invoke(Varargs)},etc, 
 | 
			
		||||
 * are routed through this method by this class, 
 | 
			
		||||
 * dropping or extending arguments with {@code nil} values as required.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * If more than one argument are required, or no arguments are required, 
 | 
			
		||||
 * or variable argument or variable return values, 
 | 
			
		||||
 * then use one of the related function
 | 
			
		||||
 * {@link ZeroArgFunction}, {@link TwoArgFunction}, {@link ThreeArgFunction}, or {@link VarArgFunction}.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * See {@link LibFunction} for more information on implementation libraries and library functions.
 | 
			
		||||
 * @see #call(LuaValue)
 | 
			
		||||
 * @see LibFunction
 | 
			
		||||
 * @see ZeroArgFunction
 | 
			
		||||
 * @see TwoArgFunction
 | 
			
		||||
 * @see ThreeArgFunction
 | 
			
		||||
 * @see VarArgFunction
 | 
			
		||||
 */
 | 
			
		||||
abstract public class OneArgFunction extends LibFunction {
 | 
			
		||||
 | 
			
		||||
	abstract public LuaValue call(LuaValue arg);
 | 
			
		||||
	
 | 
			
		||||
	/** Default constructor */
 | 
			
		||||
	public OneArgFunction() {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Constructor with specific environment
 | 
			
		||||
	 * @param env The environment to apply during constructon.
 | 
			
		||||
	 */
 | 
			
		||||
	public OneArgFunction( LuaValue env ) {
 | 
			
		||||
		this.env = env;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public final LuaValue call() {
 | 
			
		||||
		return call(NIL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public final LuaValue call(LuaValue arg1, LuaValue arg2) {
 | 
			
		||||
		return call(arg1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
 | 
			
		||||
		return call(arg1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Varargs invoke(Varargs varargs) {
 | 
			
		||||
		return call(varargs.arg1());
 | 
			
		||||
	}
 | 
			
		||||
} 
 | 
			
		||||
@@ -1,323 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaTable;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Subclass of {@link LibFunction} which implements the standard lua {@code os} library.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * It is a usable base with simplified stub functions
 | 
			
		||||
 * for library functions that cannot be implemented uniformly 
 | 
			
		||||
 * on Jse and Jme.   
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This can be installed as-is on either platform, or extended 
 | 
			
		||||
 * and refined to be used in a complete Jse implementation.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Because the nature of the {@code os} library is to encapsulate 
 | 
			
		||||
 * os-specific features, the behavior of these functions varies considerably 
 | 
			
		||||
 * from their counterparts in the C platform.  
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The following functions have limited implementations of features 
 | 
			
		||||
 * that are not supported well on Jme:
 | 
			
		||||
 * <ul>
 | 
			
		||||
 * <li>{@code execute()}</li>
 | 
			
		||||
 * <li>{@code remove()}</li>
 | 
			
		||||
 * <li>{@code rename()}</li>
 | 
			
		||||
 * <li>{@code tmpname()}</li>
 | 
			
		||||
 * </ul>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Typically, this library is included as part of a call to either 
 | 
			
		||||
 * {@link JmePlatform#standardGlobals()}
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To instantiate and use it directly, 
 | 
			
		||||
 * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LuaTable _G = new LuaTable();
 | 
			
		||||
 * LuaThread.setGlobals(_G);
 | 
			
		||||
 * _G.load(new BaseLib());
 | 
			
		||||
 * _G.load(new PackageLib());
 | 
			
		||||
 * _G.load(new OsLib());
 | 
			
		||||
 * System.out.println( _G.get("os").get("time").call() );
 | 
			
		||||
 * } </pre>
 | 
			
		||||
 * Doing so will ensure the library is properly initialized 
 | 
			
		||||
 * and loaded into the globals table. 
 | 
			
		||||
 * <p>
 | 
			
		||||
  * @see LibFunction
 | 
			
		||||
 * @see JseOsLib
 | 
			
		||||
 * @see JsePlatform
 | 
			
		||||
 * @see JmePlatform
 | 
			
		||||
 * @see <a href="http://www.lua.org/manual/5.1/manual.html#5.8">http://www.lua.org/manual/5.1/manual.html#5.8</a>
 | 
			
		||||
 */
 | 
			
		||||
public class OsLib extends VarArgFunction {
 | 
			
		||||
	public static String TMP_PREFIX    = ".luaj";
 | 
			
		||||
	public static String TMP_SUFFIX    = "tmp";
 | 
			
		||||
 | 
			
		||||
	private static final int INIT      = 0;
 | 
			
		||||
	private static final int CLOCK     = 1;
 | 
			
		||||
	private static final int DATE      = 2;
 | 
			
		||||
	private static final int DIFFTIME  = 3;
 | 
			
		||||
	private static final int EXECUTE   = 4;
 | 
			
		||||
	private static final int EXIT      = 5;
 | 
			
		||||
	private static final int GETENV    = 6;
 | 
			
		||||
	private static final int REMOVE    = 7;
 | 
			
		||||
	private static final int RENAME    = 8;
 | 
			
		||||
	private static final int SETLOCALE = 9;
 | 
			
		||||
	private static final int TIME      = 10;
 | 
			
		||||
	private static final int TMPNAME   = 11;
 | 
			
		||||
 | 
			
		||||
	private static final String[] NAMES = {
 | 
			
		||||
		"clock",
 | 
			
		||||
		"date",
 | 
			
		||||
		"difftime",
 | 
			
		||||
		"execute",
 | 
			
		||||
		"exit",
 | 
			
		||||
		"getenv",
 | 
			
		||||
		"remove",
 | 
			
		||||
		"rename",
 | 
			
		||||
		"setlocale",
 | 
			
		||||
		"time",
 | 
			
		||||
		"tmpname",
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
	private static final long t0 = System.currentTimeMillis();
 | 
			
		||||
	private static long tmpnames = t0;
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Create and OsLib instance.   
 | 
			
		||||
	 */
 | 
			
		||||
	public OsLib() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue init() {
 | 
			
		||||
		LuaTable t = new LuaTable();
 | 
			
		||||
		bind(t, this.getClass(), NAMES, CLOCK);
 | 
			
		||||
		env.set("os", t);
 | 
			
		||||
		PackageLib.instance.LOADED.set("os", t);
 | 
			
		||||
		return t;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Varargs invoke(Varargs args) {
 | 
			
		||||
		try {
 | 
			
		||||
			switch ( opcode ) {
 | 
			
		||||
			case INIT: 
 | 
			
		||||
				return init();
 | 
			
		||||
			case CLOCK:
 | 
			
		||||
				return valueOf(clock());
 | 
			
		||||
			case DATE: {
 | 
			
		||||
				String s = args.optjstring(1, null);
 | 
			
		||||
				double t = args.optdouble(2,-1);
 | 
			
		||||
				return valueOf( date(s, t==-1? System.currentTimeMillis()/1000.: t) );
 | 
			
		||||
			}
 | 
			
		||||
			case DIFFTIME:
 | 
			
		||||
				return valueOf(difftime(args.checkdouble(1),args.checkdouble(2)));
 | 
			
		||||
			case EXECUTE:
 | 
			
		||||
				return valueOf(execute(args.optjstring(1, null)));
 | 
			
		||||
			case EXIT:
 | 
			
		||||
				exit(args.optint(1, 0));
 | 
			
		||||
				return NONE;
 | 
			
		||||
			case GETENV: {
 | 
			
		||||
				final String val = getenv(args.checkjstring(1));
 | 
			
		||||
				return val!=null? valueOf(val): NIL;
 | 
			
		||||
			}
 | 
			
		||||
			case REMOVE:
 | 
			
		||||
				remove(args.checkjstring(1));
 | 
			
		||||
				return LuaValue.TRUE;
 | 
			
		||||
			case RENAME:
 | 
			
		||||
				rename(args.checkjstring(1), args.checkjstring(2));
 | 
			
		||||
				return LuaValue.TRUE;
 | 
			
		||||
			case SETLOCALE: {
 | 
			
		||||
				String s = setlocale(args.optjstring(1,null), args.optjstring(2, "all"));
 | 
			
		||||
				return s!=null? valueOf(s): NIL;
 | 
			
		||||
			}
 | 
			
		||||
			case TIME:
 | 
			
		||||
				return valueOf(time(args.arg1().isnil()? null: args.checktable(1)));
 | 
			
		||||
			case TMPNAME:
 | 
			
		||||
				return valueOf(tmpname());
 | 
			
		||||
			}
 | 
			
		||||
			return NONE;
 | 
			
		||||
		} catch ( IOException e ) {
 | 
			
		||||
			return varargsOf(NIL, valueOf(e.getMessage()));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return an approximation of the amount in seconds of CPU time used by 
 | 
			
		||||
	 * the program.
 | 
			
		||||
	 */
 | 
			
		||||
	protected double clock() {
 | 
			
		||||
		return (System.currentTimeMillis()-t0) / 1000.;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the number of seconds from time t1 to time t2. 
 | 
			
		||||
	 * In POSIX, Windows, and some other systems, this value is exactly t2-t1.
 | 
			
		||||
	 * @param t2
 | 
			
		||||
	 * @param t1
 | 
			
		||||
	 * @return diffeence in time values, in seconds
 | 
			
		||||
	 */
 | 
			
		||||
	protected double difftime(double t2, double t1) {
 | 
			
		||||
		return t2 - t1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * If the time argument is present, this is the time to be formatted 
 | 
			
		||||
	 * (see the os.time function for a description of this value). 
 | 
			
		||||
	 * Otherwise, date formats the current time.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * If format starts with '!', then the date is formatted in Coordinated 
 | 
			
		||||
	 * Universal Time. After this optional character, if format is the string 
 | 
			
		||||
	 * "*t", then date returns a table with the following fields: year 
 | 
			
		||||
	 * (four digits), month (1--12), day (1--31), hour (0--23), min (0--59), 
 | 
			
		||||
	 * sec (0--61), wday (weekday, Sunday is 1), yday (day of the year), 
 | 
			
		||||
	 * and isdst (daylight saving flag, a boolean).
 | 
			
		||||
	 * 
 | 
			
		||||
	 * If format is not "*t", then date returns the date as a string, 
 | 
			
		||||
	 * formatted according to the same rules as the C function strftime.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * When called without arguments, date returns a reasonable date and 
 | 
			
		||||
	 * time representation that depends on the host system and on the 
 | 
			
		||||
	 * current locale (that is, os.date() is equivalent to os.date("%c")).
 | 
			
		||||
	 *  
 | 
			
		||||
	 * @param format 
 | 
			
		||||
	 * @param time time since epoch, or -1 if not supplied
 | 
			
		||||
	 * @return a LString or a LTable containing date and time, 
 | 
			
		||||
	 * formatted according to the given string format.
 | 
			
		||||
	 */
 | 
			
		||||
	protected String date(String format, double time) {
 | 
			
		||||
		return new java.util.Date((long)(time*1000)).toString();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * This function is equivalent to the C function system. 
 | 
			
		||||
	 * It passes command to be executed by an operating system shell. 
 | 
			
		||||
	 * It returns a status code, which is system-dependent. 
 | 
			
		||||
	 * If command is absent, then it returns nonzero if a shell 
 | 
			
		||||
	 * is available and zero otherwise.
 | 
			
		||||
	 * @param command command to pass to the system
 | 
			
		||||
	 */ 
 | 
			
		||||
	protected int execute(String command) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Calls the C function exit, with an optional code, to terminate the host program. 
 | 
			
		||||
	 * @param code
 | 
			
		||||
	 */
 | 
			
		||||
	protected void exit(int code) {
 | 
			
		||||
		/* DAN200 START */
 | 
			
		||||
		//System.exit(code);
 | 
			
		||||
		/* DAN200 END */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the value of the process environment variable varname, 
 | 
			
		||||
	 * or null if the variable is not defined. 
 | 
			
		||||
	 * @param varname
 | 
			
		||||
	 * @return String value, or null if not defined
 | 
			
		||||
	 */
 | 
			
		||||
	protected String getenv(String varname) {
 | 
			
		||||
		return System.getProperty(varname);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Deletes the file or directory with the given name. 
 | 
			
		||||
	 * Directories must be empty to be removed. 
 | 
			
		||||
	 * If this function fails, it throws and IOException
 | 
			
		||||
	 *  
 | 
			
		||||
	 * @param filename
 | 
			
		||||
	 * @throws IOException if it fails
 | 
			
		||||
	 */
 | 
			
		||||
	protected void remove(String filename) throws IOException {
 | 
			
		||||
		throw new IOException( "not implemented" );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Renames file or directory named oldname to newname. 
 | 
			
		||||
	 * If this function fails,it throws and IOException
 | 
			
		||||
	 *  
 | 
			
		||||
	 * @param oldname old file name
 | 
			
		||||
	 * @param newname new file name
 | 
			
		||||
	 * @throws IOException if it fails
 | 
			
		||||
	 */
 | 
			
		||||
	protected void rename(String oldname, String newname) throws IOException {
 | 
			
		||||
		throw new IOException( "not implemented" );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the current locale of the program. locale is a string specifying 
 | 
			
		||||
	 * a locale; category is an optional string describing which category to change: 
 | 
			
		||||
	 * "all", "collate", "ctype", "monetary", "numeric", or "time"; the default category 
 | 
			
		||||
	 * is "all". 
 | 
			
		||||
	 * 
 | 
			
		||||
	 * If locale is the empty string, the current locale is set to an implementation-
 | 
			
		||||
	 * defined native locale. If locale is the string "C", the current locale is set 
 | 
			
		||||
	 * to the standard C locale.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * When called with null as the first argument, this function only returns the 
 | 
			
		||||
	 * name of the current locale for the given category.
 | 
			
		||||
	 *  
 | 
			
		||||
	 * @param locale
 | 
			
		||||
	 * @param category
 | 
			
		||||
	 * @return the name of the new locale, or null if the request 
 | 
			
		||||
	 * cannot be honored.
 | 
			
		||||
	 */
 | 
			
		||||
	protected String setlocale(String locale, String category) {
 | 
			
		||||
		return "C";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the current time when called without arguments, 
 | 
			
		||||
	 * or a time representing the date and time specified by the given table. 
 | 
			
		||||
	 * This table must have fields year, month, and day, 
 | 
			
		||||
	 * and may have fields hour, min, sec, and isdst 
 | 
			
		||||
	 * (for a description of these fields, see the os.date function).
 | 
			
		||||
	 * @param table
 | 
			
		||||
	 * @return long value for the time
 | 
			
		||||
	 */
 | 
			
		||||
	protected long time(LuaTable table) {
 | 
			
		||||
		return System.currentTimeMillis();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns a string with a file name that can be used for a temporary file. 
 | 
			
		||||
	 * The file must be explicitly opened before its use and explicitly removed 
 | 
			
		||||
	 * when no longer needed.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * On some systems (POSIX), this function also creates a file with that name, 
 | 
			
		||||
	 * to avoid security risks. (Someone else might create the file with wrong 
 | 
			
		||||
	 * permissions in the time between getting the name and creating the file.) 
 | 
			
		||||
	 * You still have to open the file to use it and to remove it (even if you 
 | 
			
		||||
	 * do not use it). 
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @return String filename to use
 | 
			
		||||
	 */
 | 
			
		||||
	protected String tmpname() {
 | 
			
		||||
		synchronized ( OsLib.class ) {
 | 
			
		||||
			return TMP_PREFIX+(tmpnames++)+TMP_SUFFIX;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,466 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2010-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.PrintStream;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaFunction;
 | 
			
		||||
import org.luaj.vm2.LuaString;
 | 
			
		||||
import org.luaj.vm2.LuaTable;
 | 
			
		||||
import org.luaj.vm2.LuaThread;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Subclass of {@link LibFunction} which implements the lua standard package and module 
 | 
			
		||||
 * library functions. 
 | 
			
		||||
 * 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Typically, this library is included as part of a call to either 
 | 
			
		||||
 * {@link JsePlatform#standardGlobals()} or {@link JmePlatform#standardGlobals()}
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To instantiate and use it directly, 
 | 
			
		||||
 * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LuaTable _G = new LuaTable();
 | 
			
		||||
 * LuaThread.setGlobals(_G);
 | 
			
		||||
 * _G.load(new BaseLib());
 | 
			
		||||
 * _G.load(new PackageLib());
 | 
			
		||||
 * System.out.println( _G.get("require").call(LuaValue.valueOf("hyperbolic")) );
 | 
			
		||||
 * } </pre>
 | 
			
		||||
 * In practice, the first 4 lines of the above are minimal requirements to get 
 | 
			
		||||
 * and initialize a globals table capable of basic reqire, print, and other functions, 
 | 
			
		||||
 * so it is much more convenient to use the {@link JsePlatform} and {@link JmePlatform} 
 | 
			
		||||
 * utility classes instead.  
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This has been implemented to match as closely as possible the behavior in the corresponding library in C.
 | 
			
		||||
 * However, the default filesystem search semantics are different and delegated to the bas library 
 | 
			
		||||
 * as outlined in the {@link BaseLib} and {@link JseBaseLib} documetnation. 
 | 
			
		||||
 * @see LibFunction
 | 
			
		||||
 * @see BaseLib
 | 
			
		||||
 * @see JseBaseLib
 | 
			
		||||
 * @see JsePlatform
 | 
			
		||||
 * @see JmePlatform
 | 
			
		||||
 * @see <a href="http://www.lua.org/manual/5.1/manual.html#5.3">http://www.lua.org/manual/5.1/manual.html#5.3</a>
 | 
			
		||||
 */
 | 
			
		||||
public class PackageLib extends OneArgFunction {
 | 
			
		||||
 | 
			
		||||
	public static String DEFAULT_LUA_PATH = "?.lua";
 | 
			
		||||
 | 
			
		||||
	public InputStream    STDIN   = null;
 | 
			
		||||
	public PrintStream    STDOUT  = System.out;
 | 
			
		||||
	public LuaTable       LOADED;
 | 
			
		||||
	public LuaTable       PACKAGE;
 | 
			
		||||
 | 
			
		||||
	/** Most recent instance of PackageLib */
 | 
			
		||||
	public static PackageLib instance;
 | 
			
		||||
	
 | 
			
		||||
	/** Loader that loads from preload table if found there */
 | 
			
		||||
	public LuaValue preload_loader;
 | 
			
		||||
	
 | 
			
		||||
	/** Loader that loads as a lua script using the LUA_PATH */
 | 
			
		||||
	public LuaValue lua_loader;
 | 
			
		||||
	
 | 
			
		||||
	/** Loader that loads as a Java class.  Class must have public constructor and be a LuaValue */
 | 
			
		||||
	public LuaValue java_loader;
 | 
			
		||||
	
 | 
			
		||||
	private static final LuaString _M         = valueOf("_M");
 | 
			
		||||
	private static final LuaString _NAME      = valueOf("_NAME");	
 | 
			
		||||
	private static final LuaString _PACKAGE   = valueOf("_PACKAGE");	
 | 
			
		||||
	private static final LuaString _DOT       = valueOf(".");
 | 
			
		||||
	private static final LuaString _LOADERS   = valueOf("loaders");
 | 
			
		||||
	private static final LuaString _LOADED    = valueOf("loaded");
 | 
			
		||||
	private static final LuaString _LOADLIB   = valueOf("loadlib");
 | 
			
		||||
	private static final LuaString _PRELOAD   = valueOf("preload");
 | 
			
		||||
	private static final LuaString _PATH      = valueOf("path");
 | 
			
		||||
	private static final LuaString _SEEALL    = valueOf("seeall");
 | 
			
		||||
	private static final LuaString _SENTINEL  = valueOf("\u0001");
 | 
			
		||||
	
 | 
			
		||||
	private static final int OP_MODULE         = 0;
 | 
			
		||||
	private static final int OP_REQUIRE        = 1;
 | 
			
		||||
	private static final int OP_LOADLIB        = 2;
 | 
			
		||||
	private static final int OP_SEEALL         = 3;
 | 
			
		||||
	private static final int OP_PRELOAD_LOADER = 4;
 | 
			
		||||
	private static final int OP_LUA_LOADER     = 5;
 | 
			
		||||
	private static final int OP_JAVA_LOADER    = 6;
 | 
			
		||||
	
 | 
			
		||||
	public PackageLib() {
 | 
			
		||||
		instance = this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue call(LuaValue arg) {
 | 
			
		||||
		env.set("require", new PkgLib1(env,"require",OP_REQUIRE,this));
 | 
			
		||||
		env.set("module",  new PkgLibV(env,"module",OP_MODULE,this));
 | 
			
		||||
		env.set( "package", PACKAGE=tableOf( new LuaValue[] {
 | 
			
		||||
				_LOADED,  LOADED=tableOf(),
 | 
			
		||||
				_PRELOAD, tableOf(),
 | 
			
		||||
				_PATH,    valueOf(DEFAULT_LUA_PATH),
 | 
			
		||||
				_LOADLIB, new PkgLibV(env,"loadlib",OP_LOADLIB,this),
 | 
			
		||||
				_SEEALL,  new PkgLib1(env,"seeall",OP_SEEALL,this),
 | 
			
		||||
				_LOADERS, listOf(new LuaValue[] {
 | 
			
		||||
						preload_loader = new PkgLibV(env,"preload_loader", OP_PRELOAD_LOADER,this),
 | 
			
		||||
						lua_loader     = new PkgLibV(env,"lua_loader", OP_LUA_LOADER,this),
 | 
			
		||||
						java_loader    = new PkgLibV(env,"java_loader", OP_JAVA_LOADER,this),
 | 
			
		||||
				}) }) );
 | 
			
		||||
		LOADED.set("package", PACKAGE);
 | 
			
		||||
		return env;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static final class PkgLib1 extends OneArgFunction {
 | 
			
		||||
		PackageLib lib;
 | 
			
		||||
		public PkgLib1(LuaValue env,String name, int opcode, PackageLib lib) {
 | 
			
		||||
			this.env = env;
 | 
			
		||||
			this.name = name;
 | 
			
		||||
			this.opcode = opcode;
 | 
			
		||||
			this.lib = lib;
 | 
			
		||||
		}
 | 
			
		||||
		public LuaValue call(LuaValue arg) {
 | 
			
		||||
			switch ( opcode ) {
 | 
			
		||||
			case OP_REQUIRE: 
 | 
			
		||||
				return lib.require(arg);
 | 
			
		||||
			case OP_SEEALL: { 
 | 
			
		||||
				LuaTable t = arg.checktable();
 | 
			
		||||
				LuaValue m = t.getmetatable();
 | 
			
		||||
				if ( m == null )
 | 
			
		||||
					t.setmetatable(m=tableOf());
 | 
			
		||||
				m.set( INDEX, LuaThread.getGlobals() );
 | 
			
		||||
				return NONE;
 | 
			
		||||
			}
 | 
			
		||||
			}
 | 
			
		||||
			return NIL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static final class PkgLibV extends VarArgFunction {
 | 
			
		||||
		PackageLib lib;
 | 
			
		||||
		public PkgLibV(LuaValue env,String name, int opcode, PackageLib lib) {
 | 
			
		||||
			this.env = env;
 | 
			
		||||
			this.name = name;
 | 
			
		||||
			this.opcode = opcode;
 | 
			
		||||
			this.lib = lib;
 | 
			
		||||
		}
 | 
			
		||||
		public Varargs invoke(Varargs args) {
 | 
			
		||||
			switch ( opcode ) {
 | 
			
		||||
			case OP_MODULE: 
 | 
			
		||||
				return lib.module(args);
 | 
			
		||||
			case OP_LOADLIB: 
 | 
			
		||||
				return loadlib(args);
 | 
			
		||||
			case OP_PRELOAD_LOADER: {
 | 
			
		||||
				return lib.loader_preload(args);
 | 
			
		||||
			}
 | 
			
		||||
			case OP_LUA_LOADER: {
 | 
			
		||||
				return lib.loader_Lua(args);
 | 
			
		||||
			}
 | 
			
		||||
			case OP_JAVA_LOADER: {
 | 
			
		||||
				return lib.loader_Java(args);
 | 
			
		||||
			}
 | 
			
		||||
			}
 | 
			
		||||
			return NONE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Allow packages to mark themselves as loaded */
 | 
			
		||||
	public void setIsLoaded(String name, LuaTable value) {
 | 
			
		||||
		LOADED.set(name, value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setLuaPath( String newLuaPath ) {
 | 
			
		||||
		PACKAGE.set( _PATH, valueOf(newLuaPath) );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public String tojstring() {
 | 
			
		||||
		return "package";
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	// ======================== Module, Package loading =============================
 | 
			
		||||
	/**
 | 
			
		||||
	 * module (name [, ...])
 | 
			
		||||
	 * 
 | 
			
		||||
	 * Creates a module. If there is a table in package.loaded[name], this table
 | 
			
		||||
	 * is the module. Otherwise, if there is a global table t with the given
 | 
			
		||||
	 * name, this table is the module. Otherwise creates a new table t and sets
 | 
			
		||||
	 * it as the value of the global name and the value of package.loaded[name].
 | 
			
		||||
	 * This function also initializes t._NAME with the given name, t._M with the
 | 
			
		||||
	 * module (t itself), and t._PACKAGE with the package name (the full module
 | 
			
		||||
	 * name minus last component; see below). Finally, module sets t as the new
 | 
			
		||||
	 * environment of the current function and the new value of
 | 
			
		||||
	 * package.loaded[name], so that require returns t.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * If name is a compound name (that is, one with components separated by
 | 
			
		||||
	 * dots), module creates (or reuses, if they already exist) tables for each
 | 
			
		||||
	 * component. For instance, if name is a.b.c, then module stores the module
 | 
			
		||||
	 * table in field c of field b of global a.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * This function may receive optional options after the module name, where
 | 
			
		||||
	 * each option is a function to be applied over the module.
 | 
			
		||||
	 */
 | 
			
		||||
	public Varargs module(Varargs args) {
 | 
			
		||||
		LuaString modname = args.checkstring(1);
 | 
			
		||||
		int n = args.narg();
 | 
			
		||||
		LuaValue value = LOADED.get(modname);
 | 
			
		||||
		LuaValue module;
 | 
			
		||||
		if ( ! value.istable() ) { /* not found? */
 | 
			
		||||
			
 | 
			
		||||
		    /* try global variable (and create one if it does not exist) */
 | 
			
		||||
			LuaValue globals = LuaThread.getGlobals();
 | 
			
		||||
			module = findtable( globals, modname );
 | 
			
		||||
			if ( module == null )
 | 
			
		||||
				error( "name conflict for module '"+modname+"'" );
 | 
			
		||||
			LOADED.set(modname, module);
 | 
			
		||||
		} else {
 | 
			
		||||
			module = (LuaTable) value;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		/* check whether table already has a _NAME field */
 | 
			
		||||
		LuaValue name = module.get(_NAME);
 | 
			
		||||
		if ( name.isnil() ) {
 | 
			
		||||
			modinit( module, modname );
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// set the environment of the current function
 | 
			
		||||
		LuaFunction f = LuaThread.getCallstackFunction(1);
 | 
			
		||||
		if ( f == null )
 | 
			
		||||
			error("no calling function");
 | 
			
		||||
		if ( ! f.isclosure() )
 | 
			
		||||
			error("'module' not called from a Lua function");
 | 
			
		||||
		f.setfenv(module);
 | 
			
		||||
		
 | 
			
		||||
		// apply the functions
 | 
			
		||||
		for ( int i=2; i<=n; i++ )
 | 
			
		||||
			args.arg(i).call( module );
 | 
			
		||||
		
 | 
			
		||||
		// returns no results
 | 
			
		||||
		return NONE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param table the table at which to start the search
 | 
			
		||||
	 * @param fname the name to look up or create, such as "abc.def.ghi"
 | 
			
		||||
	 * @return the table for that name, possible a new one, or null if a non-table has that name already. 
 | 
			
		||||
	 */
 | 
			
		||||
	private static final LuaValue findtable(LuaValue table, LuaString fname) {
 | 
			
		||||
		int b, e=(-1);
 | 
			
		||||
		do {
 | 
			
		||||
			e = fname.indexOf(_DOT, b=e+1 );
 | 
			
		||||
			if ( e < 0 )
 | 
			
		||||
				e = fname.m_length;
 | 
			
		||||
			LuaString key = fname.substring(b, e);
 | 
			
		||||
			LuaValue val = table.rawget(key);
 | 
			
		||||
			if ( val.isnil() ) { /* no such field? */
 | 
			
		||||
				LuaTable field = new LuaTable(); /* new table for field */
 | 
			
		||||
				table.set(key, field);
 | 
			
		||||
				table = field;
 | 
			
		||||
			} else if ( ! val.istable() ) {  /* field has a non-table value? */
 | 
			
		||||
				return null;
 | 
			
		||||
			} else {
 | 
			
		||||
				table = val;
 | 
			
		||||
			}
 | 
			
		||||
		} while ( e < fname.m_length );
 | 
			
		||||
		return table;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static final void modinit(LuaValue module, LuaString modname) {
 | 
			
		||||
		/* module._M = module */
 | 
			
		||||
		module.set(_M, module);
 | 
			
		||||
		int e = modname.lastIndexOf(_DOT);
 | 
			
		||||
		module.set(_NAME, modname );
 | 
			
		||||
		module.set(_PACKAGE, (e<0? EMPTYSTRING: modname.substring(0,e+1)) );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * require (modname)
 | 
			
		||||
	 * 
 | 
			
		||||
	 * Loads the given module. The function starts by looking into the package.loaded table to 
 | 
			
		||||
	 * determine whether modname is already loaded. If it is, then require returns the value 
 | 
			
		||||
	 * stored at package.loaded[modname]. Otherwise, it tries to find a loader for the module.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * To find a loader, require is guided by the package.loaders array. By changing this array, 
 | 
			
		||||
	 * we can change how require looks for a module. The following explanation is based on the 
 | 
			
		||||
	 * default configuration for package.loaders.
 | 
			
		||||
	 *  
 | 
			
		||||
	 * First require queries package.preload[modname]. If it has a value, this value 
 | 
			
		||||
	 * (which should be a function) is the loader. Otherwise require searches for a Lua loader 
 | 
			
		||||
	 * using the path stored in package.path. If that also fails, it searches for a C loader 
 | 
			
		||||
	 * using the path stored in package.cpath. If that also fails, it tries an all-in-one loader 
 | 
			
		||||
	 * (see package.loaders).
 | 
			
		||||
	 * 
 | 
			
		||||
	 * Once a loader is found, require calls the loader with a single argument, modname. 
 | 
			
		||||
	 * If the loader returns any value, require assigns the returned value to package.loaded[modname]. 
 | 
			
		||||
	 * If the loader returns no value and has not assigned any value to package.loaded[modname], 
 | 
			
		||||
	 * then require assigns true to this entry. In any case, require returns the final value of 
 | 
			
		||||
	 * package.loaded[modname]. 
 | 
			
		||||
	 * 
 | 
			
		||||
	 * If there is any error loading or running the module, or if it cannot find any loader for 
 | 
			
		||||
	 * the module, then require signals an error.
 | 
			
		||||
	 */	
 | 
			
		||||
	public LuaValue require( LuaValue arg ) {
 | 
			
		||||
		LuaString name = arg.checkstring();
 | 
			
		||||
		LuaValue loaded = LOADED.get(name);
 | 
			
		||||
		if ( loaded.toboolean() ) {
 | 
			
		||||
			if ( loaded == _SENTINEL )
 | 
			
		||||
				error("loop or previous error loading module '"+name+"'");
 | 
			
		||||
			return loaded;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* else must load it; iterate over available loaders */
 | 
			
		||||
		LuaTable tbl = PACKAGE.get(_LOADERS).checktable();
 | 
			
		||||
		StringBuffer sb = new StringBuffer();
 | 
			
		||||
		LuaValue chunk = null;
 | 
			
		||||
		for ( int i=1; true; i++ ) {
 | 
			
		||||
			LuaValue loader = tbl.get(i);
 | 
			
		||||
			if ( loader.isnil() ) {
 | 
			
		||||
				error( "module '"+name+"' not found: "+name+sb );				
 | 
			
		||||
		    }
 | 
			
		||||
						
 | 
			
		||||
		    /* call loader with module name as argument */
 | 
			
		||||
			chunk = loader.call(name);
 | 
			
		||||
			if ( chunk.isfunction() )
 | 
			
		||||
				break;
 | 
			
		||||
			if ( chunk.isstring() )
 | 
			
		||||
				sb.append( chunk.tojstring() );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// load the module using the loader
 | 
			
		||||
		LOADED.set(name, _SENTINEL);
 | 
			
		||||
		LuaValue result = chunk.call(name);
 | 
			
		||||
		if ( ! result.isnil() )
 | 
			
		||||
			LOADED.set( name, result );
 | 
			
		||||
		else if ( (result = LOADED.get(name)) == _SENTINEL ) 
 | 
			
		||||
			LOADED.set( name, result = LuaValue.TRUE );
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Varargs loadlib( Varargs args ) {
 | 
			
		||||
		args.checkstring(1);
 | 
			
		||||
		return varargsOf(NIL, valueOf("dynamic libraries not enabled"), valueOf("absent"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	LuaValue loader_preload( Varargs args ) {
 | 
			
		||||
		LuaString name = args.checkstring(1);
 | 
			
		||||
		LuaValue preload = PACKAGE.get(_PRELOAD).checktable();
 | 
			
		||||
		LuaValue val = preload.get(name);
 | 
			
		||||
		return val.isnil()? 
 | 
			
		||||
			valueOf("\n\tno field package.preload['"+name+"']"):
 | 
			
		||||
			val;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	LuaValue loader_Lua( Varargs args ) {
 | 
			
		||||
		String name = args.checkjstring(1);
 | 
			
		||||
		InputStream is = null;
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		// get package path
 | 
			
		||||
		LuaValue pp = PACKAGE.get(_PATH);
 | 
			
		||||
		if ( ! pp.isstring() ) 
 | 
			
		||||
			return valueOf("package.path is not a string");
 | 
			
		||||
		String path = pp.tojstring();
 | 
			
		||||
		
 | 
			
		||||
		// check the path elements
 | 
			
		||||
		int e = -1;
 | 
			
		||||
		int n = path.length();
 | 
			
		||||
		StringBuffer sb = null;
 | 
			
		||||
		name = name.replace('.','/');
 | 
			
		||||
		while ( e < n ) {
 | 
			
		||||
			
 | 
			
		||||
			// find next template
 | 
			
		||||
			int b = e+1;
 | 
			
		||||
			e = path.indexOf(';',b);
 | 
			
		||||
			if ( e < 0 )
 | 
			
		||||
				e = path.length();
 | 
			
		||||
			String template = path.substring(b,e);
 | 
			
		||||
 | 
			
		||||
			// create filename
 | 
			
		||||
			int q = template.indexOf('?');
 | 
			
		||||
			String filename = template;
 | 
			
		||||
			if ( q >= 0 ) {
 | 
			
		||||
				filename = template.substring(0,q) + name + template.substring(q+1);
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			// try loading the file
 | 
			
		||||
			Varargs v = BaseLib.loadFile(filename); 
 | 
			
		||||
			if ( v.arg1().isfunction() )
 | 
			
		||||
				return v.arg1();
 | 
			
		||||
			
 | 
			
		||||
			// report error
 | 
			
		||||
			if ( sb == null )
 | 
			
		||||
				sb = new StringBuffer();
 | 
			
		||||
			sb.append( "\n\t'"+filename+"': "+v.arg(2) );
 | 
			
		||||
		}
 | 
			
		||||
		return valueOf(sb.toString());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	LuaValue loader_Java( Varargs args ) {
 | 
			
		||||
		String name = args.checkjstring(1);
 | 
			
		||||
		String classname = toClassname( name );
 | 
			
		||||
		Class c = null;
 | 
			
		||||
		LuaValue v = null;
 | 
			
		||||
		try {
 | 
			
		||||
			c = Class.forName(classname);
 | 
			
		||||
			v = (LuaValue) c.newInstance();
 | 
			
		||||
			v.setfenv(env);
 | 
			
		||||
			return v;
 | 
			
		||||
		} catch ( ClassNotFoundException  cnfe ) {
 | 
			
		||||
			return valueOf("\n\tno class '"+classname+"'" );
 | 
			
		||||
		} catch ( Exception e ) {
 | 
			
		||||
			return valueOf("\n\tjava load failed on '"+classname+"', "+e );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Convert lua filename to valid class name */
 | 
			
		||||
	public static final String toClassname( String filename ) {
 | 
			
		||||
		int n=filename.length();
 | 
			
		||||
		int j=n;
 | 
			
		||||
		if ( filename.endsWith(".lua") )
 | 
			
		||||
			j -= 4;
 | 
			
		||||
		for ( int k=0; k<j; k++ ) {
 | 
			
		||||
			char c = filename.charAt(k);
 | 
			
		||||
			if ( (!isClassnamePart(c)) || (c=='/') || (c=='\\') ) {
 | 
			
		||||
				StringBuffer sb = new StringBuffer(j);
 | 
			
		||||
				for ( int i=0; i<j; i++ ) {
 | 
			
		||||
					c = filename.charAt(i);
 | 
			
		||||
					sb.append( 
 | 
			
		||||
							 (isClassnamePart(c))? c:
 | 
			
		||||
							 ((c=='/') || (c=='\\'))? '.': '_' ); 
 | 
			
		||||
				}
 | 
			
		||||
				return sb.toString();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return n==j? filename: filename.substring(0,j);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private static final boolean isClassnamePart(char c) {
 | 
			
		||||
		if ( (c>='a'&&c<='z') || (c>='A'&&c<='Z') || (c>='0'&&c<='9') )
 | 
			
		||||
			return true;
 | 
			
		||||
		switch ( c ) {
 | 
			
		||||
		case '.':
 | 
			
		||||
		case '$':
 | 
			
		||||
		case '_':
 | 
			
		||||
			return true;
 | 
			
		||||
		default:
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
@@ -1,57 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Interface for opening application resource files such as scripts sources.  
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This is used by required to load files that are part of 
 | 
			
		||||
 * the application, and implemented by BaseLib
 | 
			
		||||
 * for both the Jme and Jse platforms. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The Jme version of base lib {@link BaseLib} 
 | 
			
		||||
 * implements {@link BaseLib#FINDER} via {@link Class#getResourceAsStream(String)}, 
 | 
			
		||||
 * while the Jse version {@link JseBaseLib} implements it using {@link java.io.File#File(String)}.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The io library does not use this API for file manipulation.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * @see BaseLib
 | 
			
		||||
 * @see BaseLib#FINDER
 | 
			
		||||
 * @see JseBaseLib
 | 
			
		||||
 * @see JmePlatform
 | 
			
		||||
 * @see JsePlatform 
 | 
			
		||||
 */
 | 
			
		||||
public interface ResourceFinder {
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Try to open a file, or return null if not found.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @see org.luaj.vm2.lib.BaseLib
 | 
			
		||||
	 * @see org.luaj.vm2.lib.jse.JseBaseLib
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param filename
 | 
			
		||||
	 * @return InputStream, or null if not found. 
 | 
			
		||||
	 */
 | 
			
		||||
	public InputStream findResource( String filename );
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,124 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaTable;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Subclass of {@link LibFunction} which implements the lua standard {@code table} 
 | 
			
		||||
 * library. 
 | 
			
		||||
 * 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Typically, this library is included as part of a call to either 
 | 
			
		||||
 * {@link JsePlatform#standardGlobals()} or {@link JmePlatform#standardGlobals()}
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To instantiate and use it directly, 
 | 
			
		||||
 * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LuaTable _G = new LuaTable();
 | 
			
		||||
 * LuaThread.setGlobals(_G);
 | 
			
		||||
 * _G.load(new BaseLib());
 | 
			
		||||
 * _G.load(new PackageLib());
 | 
			
		||||
 * _G.load(new TableLib());
 | 
			
		||||
 * LuaValue tbl = LuaValue.listOf( new LuaValue[] {
 | 
			
		||||
 * 		LuaValue.valueOf( "abc" ),
 | 
			
		||||
 * 		LuaValue.valueOf( "def" ) } );
 | 
			
		||||
 * LuaValue sep = LuaValue.valueOf( "-" );
 | 
			
		||||
 * System.out.println( _G.get("table").get("concat").call( tbl, sep ) );
 | 
			
		||||
 * } </pre>
 | 
			
		||||
 * Doing so will ensure the library is properly initialized 
 | 
			
		||||
 * and loaded into the globals table. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This has been implemented to match as closely as possible the behavior in the corresponding library in C.
 | 
			
		||||
 * @see LibFunction
 | 
			
		||||
 * @see JsePlatform
 | 
			
		||||
 * @see JmePlatform
 | 
			
		||||
 * @see <a href="http://www.lua.org/manual/5.1/manual.html#5.5">http://www.lua.org/manual/5.1/manual.html#5.5</a>
 | 
			
		||||
 */
 | 
			
		||||
public class TableLib extends OneArgFunction {
 | 
			
		||||
 | 
			
		||||
	public TableLib() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private LuaTable init() {
 | 
			
		||||
		LuaTable t = new LuaTable();
 | 
			
		||||
		bind(t, TableLib.class, new String[] { "getn", "maxn", }, 1 );
 | 
			
		||||
		bind(t, TableLibV.class, new String[] {
 | 
			
		||||
			"remove", "concat", "insert", "sort", "foreach", "foreachi", } );
 | 
			
		||||
		env.set("table", t);
 | 
			
		||||
		PackageLib.instance.LOADED.set("table", t);
 | 
			
		||||
		return t;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue call(LuaValue arg) {
 | 
			
		||||
		switch ( opcode ) {
 | 
			
		||||
		case 0: // init library
 | 
			
		||||
			return init();
 | 
			
		||||
		case 1:  // "getn" (table) -> number
 | 
			
		||||
			return arg.checktable().getn();
 | 
			
		||||
		case 2: // "maxn"  (table) -> number 
 | 
			
		||||
			return valueOf( arg.checktable().maxn());
 | 
			
		||||
		}
 | 
			
		||||
		return NIL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static final class TableLibV extends VarArgFunction {
 | 
			
		||||
		public Varargs invoke(Varargs args) {
 | 
			
		||||
			switch ( opcode ) {
 | 
			
		||||
			case 0: { // "remove" (table [, pos]) -> removed-ele
 | 
			
		||||
				LuaTable table = args.checktable(1);
 | 
			
		||||
				int pos = args.narg()>1? args.checkint(2): 0;
 | 
			
		||||
				return table.remove(pos);
 | 
			
		||||
			}
 | 
			
		||||
			case 1: { // "concat" (table [, sep [, i [, j]]]) -> string
 | 
			
		||||
				LuaTable table = args.checktable(1);
 | 
			
		||||
				return table.concat(
 | 
			
		||||
						args.optstring(2,LuaValue.EMPTYSTRING),
 | 
			
		||||
						args.optint(3,1),
 | 
			
		||||
						args.isvalue(4)? args.checkint(4): table.length() );
 | 
			
		||||
			}
 | 
			
		||||
			case 2: { // "insert" (table, [pos,] value) -> prev-ele
 | 
			
		||||
				final LuaTable table = args.checktable(1);
 | 
			
		||||
				final int pos = args.narg()>2? args.checkint(2): 0;
 | 
			
		||||
				final LuaValue value = args.arg( args.narg()>2? 3: 2 );
 | 
			
		||||
				table.insert( pos, value );
 | 
			
		||||
				return NONE;
 | 
			
		||||
			}
 | 
			
		||||
			case 3: { // "sort" (table [, comp]) -> void
 | 
			
		||||
				LuaTable table = args.checktable(1);
 | 
			
		||||
				LuaValue compare = (args.isnoneornil(2)? NIL: args.checkfunction(2));
 | 
			
		||||
				table.sort( compare );
 | 
			
		||||
				return NONE;
 | 
			
		||||
			}
 | 
			
		||||
			case 4: { // (table, func) -> void
 | 
			
		||||
				return args.checktable(1).foreach( args.checkfunction(2) );
 | 
			
		||||
			}
 | 
			
		||||
			case 5: { // "foreachi" (table, func) -> void
 | 
			
		||||
				return args.checktable(1).foreachi( args.checkfunction(2) );
 | 
			
		||||
			}
 | 
			
		||||
			}
 | 
			
		||||
			return NONE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,80 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
 | 
			
		||||
/** Abstract base class for Java function implementations that take two arguments and 
 | 
			
		||||
 * return one value. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Subclasses need only implement {@link LuaValue#call(LuaValue,LuaValue,LuaValue)} to complete this class, 
 | 
			
		||||
 * simplifying development.  
 | 
			
		||||
 * All other uses of {@link #call()}, {@link #invoke(Varargs)},etc, 
 | 
			
		||||
 * are routed through this method by this class, 
 | 
			
		||||
 * dropping or extending arguments with {@code nil} values as required.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * If more or less than three arguments are required,  
 | 
			
		||||
 * or variable argument or variable return values, 
 | 
			
		||||
 * then use one of the related function
 | 
			
		||||
 * {@link ZeroArgFunction}, {@link OneArgFunction}, {@link TwoArgFunction}, or {@link VarArgFunction}.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * See {@link LibFunction} for more information on implementation libraries and library functions.
 | 
			
		||||
 * @see #call(LuaValue,LuaValue,LuaValue)
 | 
			
		||||
 * @see LibFunction
 | 
			
		||||
 * @see ZeroArgFunction
 | 
			
		||||
 * @see OneArgFunction
 | 
			
		||||
 * @see TwoArgFunction
 | 
			
		||||
 * @see VarArgFunction
 | 
			
		||||
 */
 | 
			
		||||
abstract public class ThreeArgFunction extends LibFunction {
 | 
			
		||||
 | 
			
		||||
	abstract public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3);
 | 
			
		||||
	
 | 
			
		||||
	/** Default constructor */
 | 
			
		||||
	public ThreeArgFunction() {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Constructor with specific environment
 | 
			
		||||
	 * @param env The environment to apply during constructon.
 | 
			
		||||
	 */
 | 
			
		||||
	public ThreeArgFunction( LuaValue env ) {
 | 
			
		||||
		this.env = env;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public final LuaValue call() {
 | 
			
		||||
		return call(NIL, NIL, NIL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public final LuaValue call(LuaValue arg) {
 | 
			
		||||
		return call(arg, NIL, NIL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue call(LuaValue arg1, LuaValue arg2) {
 | 
			
		||||
		return call(arg1, arg2, NIL);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Varargs invoke(Varargs varargs) {
 | 
			
		||||
		return call(varargs.arg1(),varargs.arg(2),varargs.arg(3));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
} 
 | 
			
		||||
@@ -1,80 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
 | 
			
		||||
/** Abstract base class for Java function implementations that take two arguments and 
 | 
			
		||||
 * return one value. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Subclasses need only implement {@link LuaValue#call(LuaValue,LuaValue)} to complete this class, 
 | 
			
		||||
 * simplifying development.  
 | 
			
		||||
 * All other uses of {@link #call()}, {@link #invoke(Varargs)},etc, 
 | 
			
		||||
 * are routed through this method by this class, 
 | 
			
		||||
 * dropping or extending arguments with {@code nil} values as required.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * If more or less than two arguments are required,  
 | 
			
		||||
 * or variable argument or variable return values, 
 | 
			
		||||
 * then use one of the related function
 | 
			
		||||
 * {@link ZeroArgFunction}, {@link OneArgFunction}, {@link ThreeArgFunction}, or {@link VarArgFunction}.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * See {@link LibFunction} for more information on implementation libraries and library functions.
 | 
			
		||||
 * @see #call(LuaValue,LuaValue)
 | 
			
		||||
 * @see LibFunction
 | 
			
		||||
 * @see ZeroArgFunction
 | 
			
		||||
 * @see OneArgFunction
 | 
			
		||||
 * @see ThreeArgFunction
 | 
			
		||||
 * @see VarArgFunction
 | 
			
		||||
 */
 | 
			
		||||
abstract public class TwoArgFunction extends LibFunction {
 | 
			
		||||
 | 
			
		||||
	abstract public LuaValue call(LuaValue arg1, LuaValue arg2);
 | 
			
		||||
	
 | 
			
		||||
	/** Default constructor */
 | 
			
		||||
	public TwoArgFunction() {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Constructor with specific environment
 | 
			
		||||
	 * @param env The environment to apply during constructon.
 | 
			
		||||
	 */
 | 
			
		||||
	public TwoArgFunction( LuaValue env ) {
 | 
			
		||||
		this.env = env;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public final LuaValue call() {
 | 
			
		||||
		return call(NIL, NIL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public final LuaValue call(LuaValue arg) {
 | 
			
		||||
		return call(arg, NIL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
 | 
			
		||||
		return call(arg1, arg2);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Varargs invoke(Varargs varargs) {
 | 
			
		||||
		return call(varargs.arg1(),varargs.arg(2));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
} 
 | 
			
		||||
@@ -1,100 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaThread;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
 | 
			
		||||
/** Abstract base class for Java function implementations that takes varaiable arguments and 
 | 
			
		||||
 * returns multiple return values. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Subclasses need only implement {@link LuaValue#invoke(Varargs)} to complete this class, 
 | 
			
		||||
 * simplifying development.  
 | 
			
		||||
 * All other uses of {@link #call(LuaValue)}, {@link #invoke()},etc, 
 | 
			
		||||
 * are routed through this method by this class,
 | 
			
		||||
 * converting arguments to {@linnk Varargs} and  
 | 
			
		||||
 * dropping or extending return values with {@code nil} values as required.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * If between one and three arguments are required, and only one return value is returned,   
 | 
			
		||||
 * {@link ZeroArgFunction}, {@link OneArgFunction}, {@link TwoArgFunction}, or {@link ThreeArgFunction}.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * See {@link LibFunction} for more information on implementation libraries and library functions.
 | 
			
		||||
 * @see #invoke(Varargs)
 | 
			
		||||
 * @see LibFunction
 | 
			
		||||
 * @see ZeroArgFunction
 | 
			
		||||
 * @see OneArgFunction
 | 
			
		||||
 * @see TwoArgFunction
 | 
			
		||||
 * @see ThreeArgFunction
 | 
			
		||||
 */
 | 
			
		||||
abstract public class VarArgFunction extends LibFunction {
 | 
			
		||||
	public VarArgFunction() {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public VarArgFunction( LuaValue env ) {
 | 
			
		||||
		this.env = env;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue call() {
 | 
			
		||||
		return invoke(NONE).arg1();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue call(LuaValue arg) {
 | 
			
		||||
		return invoke(arg).arg1();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue call(LuaValue arg1, LuaValue arg2) {
 | 
			
		||||
		return invoke(varargsOf(arg1,arg2)).arg1();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
 | 
			
		||||
		return invoke(varargsOf(arg1,arg2,arg3)).arg1();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Override and implement for the best performance. 
 | 
			
		||||
	 * May not have expected behavior for tail calls. 
 | 
			
		||||
	 * Should not be used if either:
 | 
			
		||||
	 * - function needs to be used as a module
 | 
			
		||||
	 * - function has a possibility of returning a TailcallVarargs
 | 
			
		||||
	 * @param args the arguments to the function call.
 | 
			
		||||
	 */
 | 
			
		||||
	public Varargs invoke(Varargs args) {
 | 
			
		||||
		LuaThread.CallStack cs = LuaThread.onCall(this);
 | 
			
		||||
		try {
 | 
			
		||||
			return this.onInvoke(args).eval();
 | 
			
		||||
		} finally {
 | 
			
		||||
			cs.onReturn();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Override to provide a call implementation that runs in an environment
 | 
			
		||||
	 * that can participate in setfenv, and behaves as expected 
 | 
			
		||||
	 * when returning TailcallVarargs. 
 | 
			
		||||
	 * @param args the arguments to the function call.
 | 
			
		||||
	 */
 | 
			
		||||
	public Varargs onInvoke(Varargs args) {
 | 
			
		||||
		return invoke(args);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
} 
 | 
			
		||||
@@ -1,77 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
 | 
			
		||||
/** Abstract base class for Java function implementations that take no arguments and 
 | 
			
		||||
 * return one value. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Subclasses need only implement {@link LuaValue#call()} to complete this class, 
 | 
			
		||||
 * simplifying development.  
 | 
			
		||||
 * All other uses of {@link #call(LuaValue)}, {@link #invoke(Varargs)},etc, 
 | 
			
		||||
 * are routed through this method by this class.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * If one or more arguments are required, or variable argument or variable return values, 
 | 
			
		||||
 * then use one of the related function
 | 
			
		||||
 * {@link OneArgFunction}, {@link TwoArgFunction}, {@link ThreeArgFunction}, or {@link VarArgFunction}.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * See {@link LibFunction} for more information on implementation libraries and library functions.
 | 
			
		||||
 * @see #call()
 | 
			
		||||
 * @see LibFunction
 | 
			
		||||
 * @see OneArgFunction
 | 
			
		||||
 * @see TwoArgFunction
 | 
			
		||||
 * @see ThreeArgFunction
 | 
			
		||||
 * @see VarArgFunction
 | 
			
		||||
 */
 | 
			
		||||
abstract public class ZeroArgFunction extends LibFunction {
 | 
			
		||||
 | 
			
		||||
	abstract public LuaValue call();
 | 
			
		||||
 | 
			
		||||
	/** Default constructor */
 | 
			
		||||
	public ZeroArgFunction() {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Constructor with specific environment
 | 
			
		||||
	 * @param env The environment to apply during constructon.
 | 
			
		||||
	 */
 | 
			
		||||
	public ZeroArgFunction( LuaValue env ) {
 | 
			
		||||
		this.env = env;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public LuaValue call(LuaValue arg) {
 | 
			
		||||
		return call();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue call(LuaValue arg1, LuaValue arg2) {
 | 
			
		||||
		return call();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
 | 
			
		||||
		return call();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Varargs invoke(Varargs varargs) {
 | 
			
		||||
		return call();
 | 
			
		||||
	}
 | 
			
		||||
} 
 | 
			
		||||
@@ -1,227 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib.jme;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
 | 
			
		||||
import javax.microedition.io.Connector;
 | 
			
		||||
import javax.microedition.io.StreamConnection;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaString;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.lib.BaseLib;
 | 
			
		||||
import org.luaj.vm2.lib.IoLib;
 | 
			
		||||
import org.luaj.vm2.lib.LibFunction;
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Subclass of {@link IoLib} and therefore {@link LibFunction} which implements the lua standard {@code io} 
 | 
			
		||||
 * library for the JSE platform. 
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * The implementation of the is based on CLDC 1.0 and StreamConnection.
 | 
			
		||||
 * However, seek is not supported. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Typically, this library is included as part of a call to 
 | 
			
		||||
 * {@link JmePlatform#standardGlobals()}
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To instantiate and use it directly, 
 | 
			
		||||
 * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LuaTable _G = new LuaTable();
 | 
			
		||||
 * LuaThread.setGlobals(_G);
 | 
			
		||||
 * _G.load(new BaseLib());
 | 
			
		||||
 * _G.load(new PackageLib());
 | 
			
		||||
 * _G.load(new JmeIoLib());
 | 
			
		||||
 * _G.get("io").get("write").call(LuaValue.valueOf("hello, world\n"));
 | 
			
		||||
 * } </pre>
 | 
			
		||||
 * Doing so will ensure the library is properly initialized 
 | 
			
		||||
 * and loaded into the globals table. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This has been implemented to match as closely as possible the behavior in the corresponding library in C.
 | 
			
		||||
 * @see LibFunction
 | 
			
		||||
 * @see JsePlatform
 | 
			
		||||
 * @see JmePlatform
 | 
			
		||||
 * @see IoLib
 | 
			
		||||
 * @see JseIoLib
 | 
			
		||||
 * @see <a href="http://www.lua.org/manual/5.1/manual.html#5.6">http://www.lua.org/manual/5.1/manual.html#5.6</a>
 | 
			
		||||
 */
 | 
			
		||||
public class JmeIoLib extends IoLib {
 | 
			
		||||
	
 | 
			
		||||
	public JmeIoLib() {
 | 
			
		||||
		super();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	protected File wrapStdin() throws IOException {
 | 
			
		||||
		return new FileImpl(BaseLib.instance.STDIN);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected File wrapStdout() throws IOException {
 | 
			
		||||
		return new FileImpl(BaseLib.instance.STDOUT);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException {
 | 
			
		||||
		String url = "file:///" + filename;
 | 
			
		||||
		int mode  = readMode? Connector.READ: Connector.READ_WRITE;
 | 
			
		||||
		StreamConnection conn = (StreamConnection) Connector.open( url, mode );
 | 
			
		||||
		File f = readMode? 
 | 
			
		||||
				new FileImpl(conn, conn.openInputStream(), null):
 | 
			
		||||
				new FileImpl(conn, conn.openInputStream(), conn.openOutputStream());
 | 
			
		||||
		/*
 | 
			
		||||
		if ( appendMode ) {
 | 
			
		||||
			f.seek("end",0);
 | 
			
		||||
		} else {
 | 
			
		||||
			if ( ! readMode )
 | 
			
		||||
				conn.truncate(0);
 | 
			
		||||
		}
 | 
			
		||||
		*/
 | 
			
		||||
		return f;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private static void notimplemented() throws IOException {
 | 
			
		||||
		throw new IOException("not implemented");
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected File openProgram(String prog, String mode) throws IOException {
 | 
			
		||||
		notimplemented();
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	protected File tmpFile() throws IOException {
 | 
			
		||||
		notimplemented();
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private final class FileImpl extends File {
 | 
			
		||||
		private final StreamConnection conn;
 | 
			
		||||
		private final InputStream is;
 | 
			
		||||
		private final OutputStream os;
 | 
			
		||||
		private boolean closed = false;
 | 
			
		||||
		private boolean nobuffer = false;
 | 
			
		||||
		private int lookahead = -1;
 | 
			
		||||
		private FileImpl( StreamConnection conn, InputStream is, OutputStream os ) {
 | 
			
		||||
			this.conn = conn;
 | 
			
		||||
			this.is = is;
 | 
			
		||||
			this.os = os;
 | 
			
		||||
		}
 | 
			
		||||
		private FileImpl( InputStream i ) {
 | 
			
		||||
			this( null, i, null );
 | 
			
		||||
		}
 | 
			
		||||
		private FileImpl( OutputStream o ) {
 | 
			
		||||
			this( null, null, o );
 | 
			
		||||
		}
 | 
			
		||||
		public String tojstring() {
 | 
			
		||||
			return "file ("+this.hashCode()+")";
 | 
			
		||||
		}
 | 
			
		||||
		public boolean isstdfile() {
 | 
			
		||||
			return conn == null;
 | 
			
		||||
		}
 | 
			
		||||
		public void close() throws IOException  {
 | 
			
		||||
			closed = true;
 | 
			
		||||
			if ( conn != null ) {
 | 
			
		||||
				conn.close();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public void flush() throws IOException {
 | 
			
		||||
			if ( os != null )
 | 
			
		||||
				os.flush();
 | 
			
		||||
		}
 | 
			
		||||
		public void write(LuaString s) throws IOException {
 | 
			
		||||
			if ( os != null )
 | 
			
		||||
				os.write( s.m_bytes, s.m_offset, s.m_length );
 | 
			
		||||
			else
 | 
			
		||||
				notimplemented();
 | 
			
		||||
			if ( nobuffer )
 | 
			
		||||
				flush();
 | 
			
		||||
		}
 | 
			
		||||
		public boolean isclosed() {
 | 
			
		||||
			return closed;
 | 
			
		||||
		}
 | 
			
		||||
		public int seek(String option, int pos) throws IOException {
 | 
			
		||||
			/*
 | 
			
		||||
			if ( conn != null ) {
 | 
			
		||||
				if ( "set".equals(option) ) {
 | 
			
		||||
					conn.seek(pos);
 | 
			
		||||
					return (int) conn.getFilePointer();
 | 
			
		||||
				} else if ( "end".equals(option) ) {
 | 
			
		||||
					conn.seek(conn.length()+1+pos);
 | 
			
		||||
					return (int) conn.length()+1;
 | 
			
		||||
				} else {
 | 
			
		||||
					conn.seek(conn.getFilePointer()+pos);
 | 
			
		||||
					return (int) conn.getFilePointer();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			*/
 | 
			
		||||
			notimplemented();
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		public void setvbuf(String mode, int size) {
 | 
			
		||||
			nobuffer = "no".equals(mode);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// get length remaining to read
 | 
			
		||||
		public int remaining() throws IOException {
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// peek ahead one character
 | 
			
		||||
		public int peek() throws IOException {
 | 
			
		||||
			if ( lookahead < 0 )
 | 
			
		||||
				lookahead = is.read();
 | 
			
		||||
			return lookahead;
 | 
			
		||||
		}		
 | 
			
		||||
		
 | 
			
		||||
		// return char if read, -1 if eof, throw IOException on other exception 
 | 
			
		||||
		public int read() throws IOException {
 | 
			
		||||
			if ( lookahead >= 0 ) {
 | 
			
		||||
				int c = lookahead;
 | 
			
		||||
				lookahead = -1;
 | 
			
		||||
				return c;
 | 
			
		||||
			}
 | 
			
		||||
			if ( is != null ) 
 | 
			
		||||
				return is.read();
 | 
			
		||||
			notimplemented();
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// return number of bytes read if positive, -1 if eof, throws IOException
 | 
			
		||||
		public int read(byte[] bytes, int offset, int length) throws IOException {
 | 
			
		||||
			int n,i=0;
 | 
			
		||||
			if (is!=null) {
 | 
			
		||||
				if ( length > 0 && lookahead >= 0 ) {
 | 
			
		||||
					bytes[offset] = (byte) lookahead;
 | 
			
		||||
					lookahead = -1;
 | 
			
		||||
					i += 1;
 | 
			
		||||
				}
 | 
			
		||||
				for ( ; i<length; ) {
 | 
			
		||||
					n = is.read(bytes, offset+i, length-i);
 | 
			
		||||
					if ( n < 0 )
 | 
			
		||||
						return ( i > 0 ? i : -1 );
 | 
			
		||||
					i += n;
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				notimplemented();
 | 
			
		||||
			}
 | 
			
		||||
			return length;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,130 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.lib.jme;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.compiler.LuaC;
 | 
			
		||||
import org.luaj.vm2.LoadState;
 | 
			
		||||
import org.luaj.vm2.LuaTable;
 | 
			
		||||
import org.luaj.vm2.LuaThread;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.lib.BaseLib;
 | 
			
		||||
import org.luaj.vm2.lib.CoroutineLib;
 | 
			
		||||
import org.luaj.vm2.lib.DebugLib;
 | 
			
		||||
import org.luaj.vm2.lib.MathLib;
 | 
			
		||||
import org.luaj.vm2.lib.OsLib;
 | 
			
		||||
import org.luaj.vm2.lib.PackageLib;
 | 
			
		||||
import org.luaj.vm2.lib.StringLib;
 | 
			
		||||
import org.luaj.vm2.lib.TableLib;
 | 
			
		||||
 | 
			
		||||
/** The {@link JmePlatform} class is a convenience class to standardize 
 | 
			
		||||
 * how globals tables are initialized for the JME platform. 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The JME platform, being limited, cannot implement all libraries in all aspects.  The main limitations are
 | 
			
		||||
 * <ul>
 | 
			
		||||
 * <li>Some math functions are not implemented, see {@link MathLib} for details</li>
 | 
			
		||||
 * <li>Scripts are loaded via Class.getResourceAsStream(), see {@link BaseLib} for details</li>
 | 
			
		||||
 * <li>OS functions execute(), remove(), rename(), and tmpname() vary, see {@link OsLib} for details</li>
 | 
			
		||||
 * <li>I/O seek is not implemented, see {@link JmeIoLib} for details</li>
 | 
			
		||||
 * <li>luajava is not available, see {@link LuajavaLib} for details</li>
 | 
			
		||||
 * </ul>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * It is used to allocate either a set of standard globals using 
 | 
			
		||||
 * {@link #standardGlobals()} or debug globals using {@link #debugGlobals()}
 | 
			
		||||
 * <p>
 | 
			
		||||
 * A simple example of initializing globals and using them from Java is:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LuaValue _G = JmePlatform.standardGlobals();
 | 
			
		||||
 * _G.get("print").call(LuaValue.valueOf("hello, world"));
 | 
			
		||||
 * } </pre>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Once globals are created, a simple way to load and run a script is:
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * LoadState.load( getClass().getResourceAsStream("main.lua"), "main.lua", _G ).call();
 | 
			
		||||
 * } </pre>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * although {@code require} could also be used: 
 | 
			
		||||
 * <pre> {@code
 | 
			
		||||
 * _G.get("require").call(LuaValue.valueOf("main"));
 | 
			
		||||
 * } </pre>
 | 
			
		||||
 * For this to succeed, the file "main.lua" must be a resource in the class path.
 | 
			
		||||
 * See {@link BaseLib} for details on finding scripts using {@link ResourceFinder}.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The standard globals will contain all standard libraries in their JME flavors:
 | 
			
		||||
 * <ul>
 | 
			
		||||
 * <li>{@link BaseLib}</li>
 | 
			
		||||
 * <li>{@link PackageLib}</li>
 | 
			
		||||
 * <li>{@link TableLib}</li>
 | 
			
		||||
 * <li>{@link StringLib}</li>
 | 
			
		||||
 * <li>{@link CoroutineLib}</li>
 | 
			
		||||
 * <li>{@link MathLib}</li>
 | 
			
		||||
 * <li>{@link JmeIoLib}</li>
 | 
			
		||||
 * <li>{@link OsLib}</li>
 | 
			
		||||
 * </ul>
 | 
			
		||||
 * In addition, the {@link LuaC} compiler is installed so lua files may be loaded in their source form. 
 | 
			
		||||
 * <p> 
 | 
			
		||||
 * The debug globals are simply the standard globals plus the {@code debug} library {@link DebugLib}.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The class ensures that initialization is done in the correct order, 
 | 
			
		||||
 * and that linkage is made  to {@link LuaThread#setGlobals(LuaValue)}. 
 | 
			
		||||
 * @see JsePlatform
 | 
			
		||||
 * @see LoadState
 | 
			
		||||
 */
 | 
			
		||||
public class JmePlatform {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a standard set of globals for JME including all the libraries.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @return Table of globals initialized with the standard JME libraries
 | 
			
		||||
	 * @see #debugGlobals()
 | 
			
		||||
	 * @see JsePlatform
 | 
			
		||||
	 * @see JmePlatform
 | 
			
		||||
	 */
 | 
			
		||||
	public static LuaTable standardGlobals() {
 | 
			
		||||
		LuaTable _G = new LuaTable();
 | 
			
		||||
		_G.load(new BaseLib());
 | 
			
		||||
		_G.load(new PackageLib());
 | 
			
		||||
		_G.load(new OsLib());
 | 
			
		||||
		_G.load(new MathLib());
 | 
			
		||||
		_G.load(new TableLib());
 | 
			
		||||
		_G.load(new StringLib());
 | 
			
		||||
		_G.load(new CoroutineLib());
 | 
			
		||||
		_G.load(new JmeIoLib());
 | 
			
		||||
		LuaThread.setGlobals(_G);
 | 
			
		||||
		LuaC.install();
 | 
			
		||||
		return _G;		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Create standard globals including the {@link debug} library.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @return Table of globals initialized with the standard JSE and debug libraries
 | 
			
		||||
	 * @see #standarsGlobals()
 | 
			
		||||
	 * @see JsePlatform
 | 
			
		||||
	 * @see JmePlatform
 | 
			
		||||
	 * @see DebugLib
 | 
			
		||||
	 */
 | 
			
		||||
	public static LuaTable debugGlobals() {
 | 
			
		||||
		LuaTable _G = standardGlobals();
 | 
			
		||||
		_G.load(new DebugLib());
 | 
			
		||||
		return _G;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
org.luaj.vm2.script.LuaScriptEngineFactory
 | 
			
		||||
@@ -1,223 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedReader;
 | 
			
		||||
import java.io.ByteArrayInputStream;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
import java.util.Vector;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LoadState;
 | 
			
		||||
import org.luaj.vm2.Lua;
 | 
			
		||||
import org.luaj.vm2.LuaFunction;
 | 
			
		||||
import org.luaj.vm2.LuaTable;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
import org.luaj.vm2.Varargs;
 | 
			
		||||
import org.luaj.vm2.lib.jse.JsePlatform;
 | 
			
		||||
import org.luaj.vm2.lua2java.Lua2Java;
 | 
			
		||||
import org.luaj.vm2.luajc.LuaJC;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * lua command for use in java se environments.
 | 
			
		||||
 */
 | 
			
		||||
public class lua {
 | 
			
		||||
	private static final String version = Lua._VERSION + "Copyright (c) 2009 Luaj.org.org";
 | 
			
		||||
 | 
			
		||||
	private static final String usage = 
 | 
			
		||||
		"usage: java -cp luaj-jse.jar lua [options] [script [args]].\n" +
 | 
			
		||||
		"Available options are:\n" +
 | 
			
		||||
		"  -e stat  execute string 'stat'\n" +
 | 
			
		||||
		"  -l name  require library 'name'\n" +
 | 
			
		||||
		"  -i       enter interactive mode after executing 'script'\n" +
 | 
			
		||||
		"  -v       show version information\n" +
 | 
			
		||||
		"  -j      	use lua2java source-to-source compiler\n" +
 | 
			
		||||
		"  -b      	use luajc bytecode-to-bytecode compiler (requires bcel on class path)\n" +
 | 
			
		||||
		"  -n      	nodebug - do not load debug library by default\n" +
 | 
			
		||||
		"  --       stop handling options\n" +
 | 
			
		||||
		"  -        execute stdin and stop handling options";
 | 
			
		||||
 | 
			
		||||
	private static void usageExit() {
 | 
			
		||||
		System.out.println(usage);
 | 
			
		||||
		System.exit(-1);		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static LuaValue _G;
 | 
			
		||||
	
 | 
			
		||||
	public static void main( String[] args ) throws IOException {
 | 
			
		||||
 | 
			
		||||
		// process args
 | 
			
		||||
		boolean interactive = (args.length == 0);
 | 
			
		||||
		boolean versioninfo = false;
 | 
			
		||||
		boolean processing = true;
 | 
			
		||||
		boolean nodebug = false;
 | 
			
		||||
		boolean luajc = false;
 | 
			
		||||
		boolean lua2java = false;
 | 
			
		||||
		Vector libs = null;
 | 
			
		||||
		try {
 | 
			
		||||
			// stateful argument processing
 | 
			
		||||
			for ( int i=0; i<args.length; i++ ) {
 | 
			
		||||
				if ( ! processing || ! args[i].startsWith("-") ) {
 | 
			
		||||
					// input file - defer to last stage
 | 
			
		||||
					break;
 | 
			
		||||
				} else if ( args[i].length() <= 1 ) {
 | 
			
		||||
					// input file - defer to last stage
 | 
			
		||||
					break;
 | 
			
		||||
				} else {
 | 
			
		||||
					switch ( args[i].charAt(1) ) {
 | 
			
		||||
					case 'e':
 | 
			
		||||
						if ( ++i >= args.length )
 | 
			
		||||
							usageExit();
 | 
			
		||||
						// input script - defer to last stage
 | 
			
		||||
						break;
 | 
			
		||||
					case 'b':
 | 
			
		||||
						luajc = true;
 | 
			
		||||
						break;
 | 
			
		||||
					case 'j':
 | 
			
		||||
						lua2java = true;
 | 
			
		||||
						break;
 | 
			
		||||
					case 'l':
 | 
			
		||||
						if ( ++i >= args.length )
 | 
			
		||||
							usageExit();
 | 
			
		||||
						libs = libs!=null? libs: new Vector();
 | 
			
		||||
						libs.addElement( args[i] );
 | 
			
		||||
						break;
 | 
			
		||||
					case 'i':
 | 
			
		||||
						interactive = true;
 | 
			
		||||
						break;
 | 
			
		||||
					case 'v':
 | 
			
		||||
						versioninfo = true;
 | 
			
		||||
						break;
 | 
			
		||||
					case 'n':
 | 
			
		||||
						nodebug = true;
 | 
			
		||||
						break;
 | 
			
		||||
					case '-':
 | 
			
		||||
						if ( args[i].length() > 2 )
 | 
			
		||||
							usageExit();
 | 
			
		||||
						processing = false;
 | 
			
		||||
						break;
 | 
			
		||||
					default:
 | 
			
		||||
						usageExit();
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// echo version
 | 
			
		||||
			if ( versioninfo )
 | 
			
		||||
				System.out.println(version);
 | 
			
		||||
			
 | 
			
		||||
			// new lua state
 | 
			
		||||
			_G = nodebug? JsePlatform.standardGlobals(): JsePlatform.debugGlobals();
 | 
			
		||||
			if ( luajc ) LuaJC.install();
 | 
			
		||||
			if ( lua2java) Lua2Java.install();
 | 
			
		||||
			for ( int i=0, n=libs!=null? libs.size(): 0; i<n; i++ )
 | 
			
		||||
				loadLibrary( (String) libs.elementAt(i) );
 | 
			
		||||
			
 | 
			
		||||
			// input script processing
 | 
			
		||||
			processing = true;
 | 
			
		||||
			for ( int i=0; i<args.length; i++ ) {
 | 
			
		||||
				if ( ! processing || ! args[i].startsWith("-") ) {
 | 
			
		||||
					processScript( new FileInputStream(args[i]), args[i], args, i );
 | 
			
		||||
					break;
 | 
			
		||||
				} else if ( "-".equals( args[i] ) ) {
 | 
			
		||||
					processScript( System.in, "=stdin", args, i );
 | 
			
		||||
					break;
 | 
			
		||||
				} else {
 | 
			
		||||
					switch ( args[i].charAt(1) ) {
 | 
			
		||||
					case 'l':
 | 
			
		||||
						++i;
 | 
			
		||||
						break;
 | 
			
		||||
					case 'e':
 | 
			
		||||
						++i;
 | 
			
		||||
						processScript( new ByteArrayInputStream(args[i].getBytes()), "string", args, i );
 | 
			
		||||
						break;
 | 
			
		||||
					case '-':
 | 
			
		||||
						processing = false;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			if ( interactive )
 | 
			
		||||
				interactiveMode();
 | 
			
		||||
			
 | 
			
		||||
		} catch ( IOException ioe ) {
 | 
			
		||||
			System.err.println( ioe.toString() );
 | 
			
		||||
			System.exit(-2);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static void loadLibrary( String libname ) throws IOException {
 | 
			
		||||
		LuaValue slibname =LuaValue.valueOf(libname); 
 | 
			
		||||
		try {
 | 
			
		||||
			// load via plain require
 | 
			
		||||
			_G.get("require").call(slibname);
 | 
			
		||||
		} catch ( Exception e ) {
 | 
			
		||||
			try {
 | 
			
		||||
				// load as java class
 | 
			
		||||
				LuaValue v = (LuaValue) Class.forName(libname).newInstance(); 
 | 
			
		||||
				v.setfenv(_G);
 | 
			
		||||
				v.call(slibname, _G);
 | 
			
		||||
			} catch ( Exception f ) {
 | 
			
		||||
				throw new IOException("loadLibrary("+libname+") failed: "+e+","+f );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private static void processScript( InputStream script, String chunkname, String[] args, int firstarg ) throws IOException {
 | 
			
		||||
		try {
 | 
			
		||||
			LuaFunction c;
 | 
			
		||||
			try {
 | 
			
		||||
				c = LoadState.load(script, chunkname, _G);
 | 
			
		||||
			} finally {
 | 
			
		||||
				script.close();
 | 
			
		||||
			}
 | 
			
		||||
			Varargs scriptargs = (args!=null? setGlobalArg(args, firstarg): LuaValue.NONE);
 | 
			
		||||
			c.invoke( scriptargs );
 | 
			
		||||
		} catch ( Exception e ) {
 | 
			
		||||
			e.printStackTrace( System.err );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static Varargs setGlobalArg(String[] args, int i) {
 | 
			
		||||
		LuaTable arg = LuaValue.tableOf();
 | 
			
		||||
		for ( int j=0; j<args.length; j++ )
 | 
			
		||||
			arg.set( j-i, LuaValue.valueOf(args[j]) );
 | 
			
		||||
		_G.set( "arg", arg );
 | 
			
		||||
		return _G.get("unpack").invoke(arg);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static void interactiveMode( ) throws IOException {
 | 
			
		||||
		BufferedReader reader = new BufferedReader( new InputStreamReader( System.in ) );
 | 
			
		||||
		while ( true ) {
 | 
			
		||||
			System.out.print("> ");
 | 
			
		||||
			System.out.flush();
 | 
			
		||||
			String line = reader.readLine();
 | 
			
		||||
			if ( line == null )
 | 
			
		||||
				return;
 | 
			
		||||
			processScript( new ByteArrayInputStream(line.getBytes()), "=stdin", null, 0 );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,213 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2010 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.PrintWriter;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.Lua;
 | 
			
		||||
import org.luaj.vm2.ast.Chunk;
 | 
			
		||||
import org.luaj.vm2.lib.jse.JsePlatform;
 | 
			
		||||
import org.luaj.vm2.lua2java.JavaCodeGen;
 | 
			
		||||
import org.luaj.vm2.parser.LuaParser;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compile lua sources into java sources. 
 | 
			
		||||
 */
 | 
			
		||||
public class lua2java {
 | 
			
		||||
	private static final String version = Lua._VERSION + "Copyright (C) 2010 luaj.org";
 | 
			
		||||
 | 
			
		||||
	private static final String usage = 
 | 
			
		||||
		"usage: java -cp luaj-jse.jar lua2java [options] fileordir [, fileordir ...]\n" +
 | 
			
		||||
		"Available options are:\n" +
 | 
			
		||||
		"  -		process stdin\n" +
 | 
			
		||||
		"  -s src	source directory\n" +
 | 
			
		||||
		"  -d dir	destination directory\n" +
 | 
			
		||||
		"  -p pkg	package prefix to apply to all classes\n" +
 | 
			
		||||
		"  -e enc	override default character encoding\n" +
 | 
			
		||||
		"  -r		recursively compile all\n" +
 | 
			
		||||
		"  -v   	verbose\n";
 | 
			
		||||
	
 | 
			
		||||
	private static void usageExit() {
 | 
			
		||||
		System.out.println(usage);
 | 
			
		||||
		System.exit(-1);		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private String srcdir = null;
 | 
			
		||||
	private String destdir = null;
 | 
			
		||||
	private String pkgprefix = null;
 | 
			
		||||
	private String encoding = "ISO8859-1";
 | 
			
		||||
	private boolean recurse = false;
 | 
			
		||||
	private boolean verbose = false;
 | 
			
		||||
	private List files = new ArrayList();
 | 
			
		||||
 | 
			
		||||
	public static void main( String[] args ) throws IOException {
 | 
			
		||||
		new lua2java( args );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private lua2java( String[] args ) throws IOException {
 | 
			
		||||
		
 | 
			
		||||
		// process args
 | 
			
		||||
		try {
 | 
			
		||||
			List seeds = new ArrayList ();
 | 
			
		||||
			
 | 
			
		||||
			// get stateful args
 | 
			
		||||
			for ( int i=0; i<args.length; i++ ) {
 | 
			
		||||
				if ( ! args[i].startsWith("-") ) {
 | 
			
		||||
					seeds.add(args[i]);
 | 
			
		||||
				} else {
 | 
			
		||||
					switch ( args[i].charAt(1) ) {
 | 
			
		||||
					case 's':
 | 
			
		||||
						if ( ++i >= args.length )
 | 
			
		||||
							usageExit();
 | 
			
		||||
						srcdir = args[i];
 | 
			
		||||
						break;
 | 
			
		||||
					case 'd':
 | 
			
		||||
						if ( ++i >= args.length )
 | 
			
		||||
							usageExit();
 | 
			
		||||
						destdir = args[i];
 | 
			
		||||
						break;
 | 
			
		||||
					case 'p':
 | 
			
		||||
						if ( ++i >= args.length )
 | 
			
		||||
							usageExit();
 | 
			
		||||
						pkgprefix = args[i];
 | 
			
		||||
						break;
 | 
			
		||||
					case 'e':
 | 
			
		||||
						if ( ++i >= args.length )
 | 
			
		||||
							usageExit();
 | 
			
		||||
						encoding = args[i];
 | 
			
		||||
						break;
 | 
			
		||||
					case 'r':
 | 
			
		||||
						recurse = true;
 | 
			
		||||
						break;
 | 
			
		||||
					case 'v':
 | 
			
		||||
						verbose = true;
 | 
			
		||||
						break;
 | 
			
		||||
					default:
 | 
			
		||||
						usageExit();
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			// echo version
 | 
			
		||||
			if ( verbose ) {
 | 
			
		||||
				System.out.println(version);
 | 
			
		||||
				System.out.println("srcdir: "+srcdir);
 | 
			
		||||
				System.out.println("destdir: "+destdir);
 | 
			
		||||
				System.out.println("files: "+seeds);
 | 
			
		||||
				System.out.println("encoding: "+encoding);
 | 
			
		||||
				System.out.println("recurse: "+recurse);
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			// need at least one seed
 | 
			
		||||
			if ( seeds.size() <= 0 ) {
 | 
			
		||||
				System.err.println(usage);
 | 
			
		||||
				System.exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// collect up files to process
 | 
			
		||||
			for ( int i=0; i<seeds.size(); i++ )
 | 
			
		||||
				collectFiles( srcdir+"/"+seeds.get(i) );
 | 
			
		||||
			
 | 
			
		||||
			// check for at least one file
 | 
			
		||||
			if ( files.size() <= 0 ) {
 | 
			
		||||
				System.err.println("no files found in "+seeds);
 | 
			
		||||
				System.exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			// process input files
 | 
			
		||||
			JsePlatform.standardGlobals();
 | 
			
		||||
			for ( int i=0,n=files.size(); i<n; i++ )
 | 
			
		||||
				processFile( (InputFile) files.get(i) );
 | 
			
		||||
			
 | 
			
		||||
		} catch ( Exception ioe ) {
 | 
			
		||||
			System.err.println( ioe.toString() );
 | 
			
		||||
			System.exit(-2);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void collectFiles(String path) {
 | 
			
		||||
		File f = new File(path);
 | 
			
		||||
		if ( f.isDirectory() && recurse )
 | 
			
		||||
			scandir(f,pkgprefix);
 | 
			
		||||
		else if ( f.isFile() ) {
 | 
			
		||||
			File dir = f.getAbsoluteFile().getParentFile();
 | 
			
		||||
			if ( dir != null )
 | 
			
		||||
				scanfile( dir, f, pkgprefix );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	private void scandir(File dir, String javapackage) {
 | 
			
		||||
		File[] f = dir.listFiles();
 | 
			
		||||
		for ( int i=0; i<f.length; i++ ) 
 | 
			
		||||
			scanfile( dir, f[i], javapackage );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void scanfile(File dir, File f, String javapackage) {
 | 
			
		||||
		if ( f.exists() ) {
 | 
			
		||||
			if ( f.isDirectory() && recurse )
 | 
			
		||||
				scandir( f, (javapackage!=null? javapackage+"."+f.getName(): f.getName()) );
 | 
			
		||||
			else if ( f.isFile() && f.getName().endsWith(".lua") )
 | 
			
		||||
				files.add( new InputFile(dir,f,javapackage) );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	class InputFile {
 | 
			
		||||
		public File infile;
 | 
			
		||||
		public File outdir;
 | 
			
		||||
		public File outfile;
 | 
			
		||||
		public String javapackage;
 | 
			
		||||
		public String javaclassname;
 | 
			
		||||
		public InputFile(File dir, File f, String javapackage) {
 | 
			
		||||
			String outdirpath = javapackage!=null? destdir+"/"+javapackage.replace('.', '/'): destdir;
 | 
			
		||||
			this.javaclassname = f.getName().substring(0,f.getName().lastIndexOf('.'));
 | 
			
		||||
			this.javapackage = javapackage;
 | 
			
		||||
			this.infile = f;
 | 
			
		||||
			this.outdir = new File(outdirpath);
 | 
			
		||||
			this.outfile = new File(outdirpath+"/"+this.javaclassname+".java");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void processFile( InputFile inf ) {
 | 
			
		||||
		inf.outdir.mkdirs();
 | 
			
		||||
		try {
 | 
			
		||||
			if ( verbose ) 
 | 
			
		||||
				System.out.println(
 | 
			
		||||
					"pkg="+inf.javapackage+" file="+inf.javaclassname+".java dest="+inf.outfile+" src="+inf.infile);
 | 
			
		||||
			FileInputStream in = new FileInputStream(inf.infile);
 | 
			
		||||
			FileOutputStream out = new FileOutputStream(inf.outfile);
 | 
			
		||||
			PrintWriter pw = new PrintWriter(out);
 | 
			
		||||
		    LuaParser parser = new LuaParser(in,encoding);
 | 
			
		||||
		    Chunk chunk = parser.Chunk();
 | 
			
		||||
			new JavaCodeGen(chunk,pw,inf.javapackage,inf.javaclassname);
 | 
			
		||||
			pw.close();
 | 
			
		||||
			out.close();
 | 
			
		||||
			in.close();
 | 
			
		||||
		} catch ( Exception e ) {
 | 
			
		||||
			e.printStackTrace( System.err );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,181 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.Lua;
 | 
			
		||||
import org.luaj.vm2.Print;
 | 
			
		||||
import org.luaj.vm2.Prototype;
 | 
			
		||||
import org.luaj.vm2.compiler.DumpState;
 | 
			
		||||
import org.luaj.vm2.compiler.LuaC;
 | 
			
		||||
import org.luaj.vm2.lib.jse.JsePlatform;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compiler for lua files to lua bytecode. 
 | 
			
		||||
 */
 | 
			
		||||
public class luac {
 | 
			
		||||
	private static final String version = Lua._VERSION + "Copyright (C) 2009 luaj.org";
 | 
			
		||||
 | 
			
		||||
	private static final String usage = 
 | 
			
		||||
		"usage: java -cp luaj-jse.jar luac [options] [filenames].\n" +
 | 
			
		||||
		"Available options are:\n" +
 | 
			
		||||
		"  -        process stdin\n" +
 | 
			
		||||
		"  -l       list\n" +
 | 
			
		||||
		"  -o name  output to file 'name' (default is \"luac.out\")\n" +
 | 
			
		||||
		"  -p       parse only\n" +
 | 
			
		||||
		"  -s       strip debug information\n" +
 | 
			
		||||
		"  -e       little endian format for numbers\n" +
 | 
			
		||||
		"  -i<n>    number format 'n', (n=0,1 or 4, default="+DumpState.NUMBER_FORMAT_DEFAULT+")\n" +
 | 
			
		||||
		"  -v       show version information\n" +
 | 
			
		||||
		"  --       stop handling options\n";
 | 
			
		||||
	
 | 
			
		||||
	private static void usageExit() {
 | 
			
		||||
		System.out.println(usage);
 | 
			
		||||
		System.exit(-1);		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private boolean list = false;
 | 
			
		||||
	private String output = "luac.out";
 | 
			
		||||
	private boolean parseonly = false;
 | 
			
		||||
	private boolean stripdebug = false;
 | 
			
		||||
	private boolean littleendian = false;
 | 
			
		||||
	private int numberformat = DumpState.NUMBER_FORMAT_DEFAULT;
 | 
			
		||||
	private boolean versioninfo = false;
 | 
			
		||||
	private boolean processing = true;
 | 
			
		||||
 | 
			
		||||
	public static void main( String[] args ) throws IOException {
 | 
			
		||||
		new luac( args );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private luac( String[] args ) throws IOException {
 | 
			
		||||
		
 | 
			
		||||
		// process args
 | 
			
		||||
		try {
 | 
			
		||||
			// get stateful args
 | 
			
		||||
			for ( int i=0; i<args.length; i++ ) {
 | 
			
		||||
				if ( ! processing || ! args[i].startsWith("-") ) {
 | 
			
		||||
					// input file - defer to next stage
 | 
			
		||||
				} else if ( args[i].length() <= 1 ) {
 | 
			
		||||
					// input file - defer to next stage
 | 
			
		||||
				} else {
 | 
			
		||||
					switch ( args[i].charAt(1) ) {
 | 
			
		||||
					case 'l':
 | 
			
		||||
						list = true;
 | 
			
		||||
						break;
 | 
			
		||||
					case 'o':
 | 
			
		||||
						if ( ++i >= args.length )
 | 
			
		||||
							usageExit();
 | 
			
		||||
						output = args[i];
 | 
			
		||||
						break;
 | 
			
		||||
					case 'p':
 | 
			
		||||
						parseonly = true;
 | 
			
		||||
						break;
 | 
			
		||||
					case 's':
 | 
			
		||||
						stripdebug = true;
 | 
			
		||||
						break;
 | 
			
		||||
					case 'e':
 | 
			
		||||
						littleendian = true;
 | 
			
		||||
						break;
 | 
			
		||||
					case 'i':
 | 
			
		||||
						if ( args[i].length() <= 2 )
 | 
			
		||||
							usageExit();
 | 
			
		||||
						numberformat = Integer.parseInt(args[i].substring(2));
 | 
			
		||||
						break;
 | 
			
		||||
					case 'v':
 | 
			
		||||
						versioninfo = true;
 | 
			
		||||
						break;
 | 
			
		||||
					case '-':
 | 
			
		||||
						if ( args[i].length() > 2 )
 | 
			
		||||
							usageExit();
 | 
			
		||||
						processing = false;
 | 
			
		||||
						break;
 | 
			
		||||
					default:
 | 
			
		||||
						usageExit();
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			// echo version
 | 
			
		||||
			if ( versioninfo )
 | 
			
		||||
				System.out.println(version);
 | 
			
		||||
 | 
			
		||||
			// open output file
 | 
			
		||||
			OutputStream fos = new FileOutputStream( output );
 | 
			
		||||
			
 | 
			
		||||
			// process input files
 | 
			
		||||
			try {
 | 
			
		||||
				JsePlatform.standardGlobals();
 | 
			
		||||
				processing = true;
 | 
			
		||||
				for ( int i=0; i<args.length; i++ ) {
 | 
			
		||||
					if ( ! processing || ! args[i].startsWith("-") ) {
 | 
			
		||||
						String chunkname = args[i].substring(0,args[i].length()-4);
 | 
			
		||||
						processScript( new FileInputStream(args[i]), chunkname, fos );
 | 
			
		||||
					} else if ( args[i].length() <= 1 ) {
 | 
			
		||||
						processScript( System.in, "=stdin", fos );
 | 
			
		||||
					} else {
 | 
			
		||||
						switch ( args[i].charAt(1) ) {
 | 
			
		||||
						case 'o':
 | 
			
		||||
							++i;
 | 
			
		||||
							break;
 | 
			
		||||
						case '-':
 | 
			
		||||
							processing = false;
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} finally {
 | 
			
		||||
				fos.close();
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
		} catch ( IOException ioe ) {
 | 
			
		||||
			System.err.println( ioe.toString() );
 | 
			
		||||
			System.exit(-2);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void processScript( InputStream script, String chunkname, OutputStream out ) throws IOException {
 | 
			
		||||
		try {
 | 
			
		||||
	        // create the chunk
 | 
			
		||||
	        Prototype chunk = LuaC.instance.compile(script, chunkname);
 | 
			
		||||
 | 
			
		||||
	        // list the chunk
 | 
			
		||||
	        if (list)
 | 
			
		||||
	            Print.printCode(chunk);
 | 
			
		||||
 | 
			
		||||
	        // write out the chunk
 | 
			
		||||
	        if (!parseonly) {
 | 
			
		||||
	            DumpState.dump(chunk, out, stripdebug, numberformat, littleendian);
 | 
			
		||||
	        }
 | 
			
		||||
	        
 | 
			
		||||
		} catch ( Exception e ) {
 | 
			
		||||
			e.printStackTrace( System.err );
 | 
			
		||||
		} finally {
 | 
			
		||||
			script.close();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,245 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Enumeration;
 | 
			
		||||
import java.util.Hashtable;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.Lua;
 | 
			
		||||
import org.luaj.vm2.lib.jse.JsePlatform;
 | 
			
		||||
import org.luaj.vm2.luajc.LuaJC;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compiler for lua files to compile lua sources or lua binaries into java classes. 
 | 
			
		||||
 */
 | 
			
		||||
public class luajc {
 | 
			
		||||
	private static final String version = Lua._VERSION + "Copyright (C) 2009 luaj.org";
 | 
			
		||||
 | 
			
		||||
	private static final String usage = 
 | 
			
		||||
		"usage: java -cp luaj-jse.jar,bcel-5.2.jar luajc [options] fileordir [, fileordir ...]\n" +
 | 
			
		||||
		"Available options are:\n" +
 | 
			
		||||
		"  -        process stdin\n" +
 | 
			
		||||
		"  -s src	source directory\n" +
 | 
			
		||||
		"  -d dir	destination directory\n" +
 | 
			
		||||
		"  -p pkg	package prefix to apply to all classes\n" +
 | 
			
		||||
		"  -r		recursively compile all\n" +
 | 
			
		||||
		"  -l		load classes to verify generated bytecode\n" +
 | 
			
		||||
		"  -v   	verbose\n";
 | 
			
		||||
	
 | 
			
		||||
	private static void usageExit() {
 | 
			
		||||
		System.out.println(usage);
 | 
			
		||||
		System.exit(-1);		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private String srcdir = null;
 | 
			
		||||
	private String destdir = null;
 | 
			
		||||
	private boolean recurse = false;
 | 
			
		||||
	private boolean verbose = false;
 | 
			
		||||
	private boolean loadclasses = false;
 | 
			
		||||
	private String pkgprefix = null;
 | 
			
		||||
	private List files = new ArrayList();
 | 
			
		||||
 | 
			
		||||
	public static void main( String[] args ) throws IOException {
 | 
			
		||||
		new luajc( args );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private luajc( String[] args ) throws IOException {
 | 
			
		||||
		
 | 
			
		||||
		// process args
 | 
			
		||||
		List seeds = new ArrayList ();
 | 
			
		||||
		
 | 
			
		||||
		// get stateful args
 | 
			
		||||
		for ( int i=0; i<args.length; i++ ) {
 | 
			
		||||
			if ( ! args[i].startsWith("-") ) {
 | 
			
		||||
				seeds.add(args[i]);
 | 
			
		||||
			} else {
 | 
			
		||||
				switch ( args[i].charAt(1) ) {
 | 
			
		||||
				case 's':
 | 
			
		||||
					if ( ++i >= args.length )
 | 
			
		||||
						usageExit();
 | 
			
		||||
					srcdir = args[i];
 | 
			
		||||
					break;
 | 
			
		||||
				case 'd':
 | 
			
		||||
					if ( ++i >= args.length )
 | 
			
		||||
						usageExit();
 | 
			
		||||
					destdir = args[i];
 | 
			
		||||
					break;
 | 
			
		||||
				case 'l':
 | 
			
		||||
					loadclasses = true;
 | 
			
		||||
					break;
 | 
			
		||||
				case 'p':
 | 
			
		||||
					if ( ++i >= args.length )
 | 
			
		||||
						usageExit();
 | 
			
		||||
					pkgprefix = args[i];
 | 
			
		||||
					break;
 | 
			
		||||
				case 'r':
 | 
			
		||||
					recurse = true;
 | 
			
		||||
					break;
 | 
			
		||||
				case 'v':
 | 
			
		||||
					verbose = true;
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					usageExit();
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// echo version
 | 
			
		||||
		if ( verbose ) {
 | 
			
		||||
			System.out.println(version);
 | 
			
		||||
			System.out.println("srcdir: "+srcdir);
 | 
			
		||||
			System.out.println("destdir: "+srcdir);
 | 
			
		||||
			System.out.println("files: "+seeds);
 | 
			
		||||
			System.out.println("recurse: "+recurse);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// need at least one seed
 | 
			
		||||
		if ( seeds.size() <= 0 ) {
 | 
			
		||||
			System.err.println(usage);
 | 
			
		||||
			System.exit(-1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// collect up files to process
 | 
			
		||||
		for ( int i=0; i<seeds.size(); i++ )
 | 
			
		||||
			collectFiles( srcdir+"/"+seeds.get(i) );
 | 
			
		||||
		
 | 
			
		||||
		// check for at least one file
 | 
			
		||||
		if ( files.size() <= 0 ) {
 | 
			
		||||
			System.err.println("no files found in "+seeds);
 | 
			
		||||
			System.exit(-1);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// process input files
 | 
			
		||||
		JsePlatform.standardGlobals();
 | 
			
		||||
		for ( int i=0,n=files.size(); i<n; i++ )
 | 
			
		||||
			processFile( (InputFile) files.get(i) );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void collectFiles(String path) {
 | 
			
		||||
		File f = new File(path);
 | 
			
		||||
		if ( f.isDirectory() && recurse )
 | 
			
		||||
			scandir(f,pkgprefix);
 | 
			
		||||
		else if ( f.isFile() ) {
 | 
			
		||||
			File dir = f.getAbsoluteFile().getParentFile();
 | 
			
		||||
			if ( dir != null )
 | 
			
		||||
				scanfile( dir, f, pkgprefix );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	private void scandir(File dir, String javapackage) {
 | 
			
		||||
		File[] f = dir.listFiles();
 | 
			
		||||
		for ( int i=0; i<f.length; i++ ) 
 | 
			
		||||
			scanfile( dir, f[i], javapackage );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void scanfile(File dir, File f, String javapackage) {
 | 
			
		||||
		if ( f.exists() ) {
 | 
			
		||||
			if ( f.isDirectory() && recurse )
 | 
			
		||||
				scandir( f, (javapackage!=null? javapackage+"."+f.getName(): f.getName()) );
 | 
			
		||||
			else if ( f.isFile() && f.getName().endsWith(".lua") )
 | 
			
		||||
				files.add( new InputFile(dir,f,javapackage) );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	class InputFile {
 | 
			
		||||
		public String luachunkname;
 | 
			
		||||
		public String srcfilename;
 | 
			
		||||
		public File infile;
 | 
			
		||||
		public File outdir;
 | 
			
		||||
		public String javapackage;
 | 
			
		||||
		
 | 
			
		||||
		public InputFile(File dir, File f, String javapackage) {
 | 
			
		||||
			this.infile = f;
 | 
			
		||||
			String subdir = javapackage!=null? javapackage.replace('.', '/'): null;
 | 
			
		||||
			String outdirpath = subdir!=null? destdir+"/"+subdir: destdir;
 | 
			
		||||
			this.javapackage = javapackage;
 | 
			
		||||
			this.srcfilename = (subdir!=null? subdir+"/": "")+infile.getName();
 | 
			
		||||
			this.luachunkname = (subdir!=null? subdir+"/": "")+infile.getName().substring( 0, infile.getName().lastIndexOf('.') );
 | 
			
		||||
			this.infile = f;
 | 
			
		||||
			this.outdir = new File(outdirpath);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
	private void processFile( InputFile inf ) {
 | 
			
		||||
		inf.outdir.mkdirs();
 | 
			
		||||
		try {
 | 
			
		||||
			if ( verbose ) 
 | 
			
		||||
				System.out.println("chunk="+inf.luachunkname+" srcfile="+inf.srcfilename);
 | 
			
		||||
 | 
			
		||||
	        // create the chunk
 | 
			
		||||
			FileInputStream fis = new FileInputStream( inf.infile );
 | 
			
		||||
			final Hashtable t = LuaJC.getInstance().compileAll(fis, inf.luachunkname, inf.srcfilename);
 | 
			
		||||
			fis.close();
 | 
			
		||||
			
 | 
			
		||||
	        // write out the chunk
 | 
			
		||||
        	for ( Enumeration e = t.keys(); e.hasMoreElements(); ) {
 | 
			
		||||
        		String key = (String) e.nextElement();
 | 
			
		||||
        		byte[] bytes = (byte[]) t.get(key);
 | 
			
		||||
        		if ( key.indexOf('/')>=0 ) {
 | 
			
		||||
        			String d = (destdir!=null? destdir+"/": "")+key.substring(0,key.lastIndexOf('/'));
 | 
			
		||||
        			new File(d).mkdirs();
 | 
			
		||||
        		}
 | 
			
		||||
        		String destpath = (destdir!=null? destdir+"/": "") + key + ".class";
 | 
			
		||||
    			if ( verbose )
 | 
			
		||||
    				System.out.println( "  "+destpath +" ("+bytes.length+" bytes)");
 | 
			
		||||
	        	FileOutputStream fos = new FileOutputStream( destpath );
 | 
			
		||||
	        	fos.write( bytes );
 | 
			
		||||
	        	fos.close();
 | 
			
		||||
	        }
 | 
			
		||||
 | 
			
		||||
        	// try to load the files
 | 
			
		||||
        	if ( loadclasses ) {
 | 
			
		||||
				ClassLoader loader = new ClassLoader() {
 | 
			
		||||
			         public Class findClass(String classname) throws ClassNotFoundException {
 | 
			
		||||
			        	 byte[] bytes = (byte[]) t.get(classname);
 | 
			
		||||
			        	 if ( bytes != null )
 | 
			
		||||
			        		 return defineClass(classname, bytes, 0, bytes.length);
 | 
			
		||||
			        	 return super.findClass(classname);
 | 
			
		||||
			         }
 | 
			
		||||
				};
 | 
			
		||||
            	for ( Enumeration e = t.keys(); e.hasMoreElements(); ) {
 | 
			
		||||
                	String classname = (String) e.nextElement();
 | 
			
		||||
	        		try {
 | 
			
		||||
                		Class c = loader.loadClass(classname);
 | 
			
		||||
                		Object o = c.newInstance();
 | 
			
		||||
                		if ( verbose )
 | 
			
		||||
    	        			System.out.println("    loaded "+classname+" as "+o );
 | 
			
		||||
	        		} catch ( Exception ex ) {
 | 
			
		||||
	        			System.out.flush();
 | 
			
		||||
	        			System.err.println("    failed to load "+classname+": "+ex );
 | 
			
		||||
	        			System.err.flush();
 | 
			
		||||
	        		}
 | 
			
		||||
            	}
 | 
			
		||||
        	}
 | 
			
		||||
        	
 | 
			
		||||
		} catch ( Exception e ) {
 | 
			
		||||
			System.err.println("    failed to load "+inf.srcfilename+": "+e );
 | 
			
		||||
			e.printStackTrace( System.err );
 | 
			
		||||
			System.err.flush();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,41 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2010 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.ast;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class Block extends Stat {
 | 
			
		||||
	
 | 
			
		||||
	public List<Stat> stats = new ArrayList<Stat>();
 | 
			
		||||
	public NameScope scope;
 | 
			
		||||
	
 | 
			
		||||
	public void add(Stat s) {
 | 
			
		||||
		if ( s == null )
 | 
			
		||||
			return;
 | 
			
		||||
		stats.add(s);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void accept(Visitor visitor) {
 | 
			
		||||
		visitor.visit(this);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,34 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2010 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.ast;
 | 
			
		||||
 | 
			
		||||
public class Chunk {
 | 
			
		||||
	public final Block block;
 | 
			
		||||
	
 | 
			
		||||
	public Chunk(Block b) {
 | 
			
		||||
		this.block = b;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void accept( Visitor visitor ) {
 | 
			
		||||
		visitor.visit( this );
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,313 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2010 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.ast;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.Lua;
 | 
			
		||||
import org.luaj.vm2.LuaValue;
 | 
			
		||||
 | 
			
		||||
abstract
 | 
			
		||||
public class Exp {
 | 
			
		||||
	abstract public void accept(Visitor visitor);
 | 
			
		||||
 | 
			
		||||
	public static Exp constant(LuaValue value) {
 | 
			
		||||
		return new Constant(value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Exp numberconstant(String token) {		
 | 
			
		||||
		return new Constant( LuaValue.valueOf(token).tonumber() );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Exp varargs() {
 | 
			
		||||
		return new VarargsExp();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Exp tableconstructor(TableConstructor tc) {
 | 
			
		||||
		return tc;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Exp unaryexp(int op, Exp rhs) {
 | 
			
		||||
		if ( rhs instanceof BinopExp ) {
 | 
			
		||||
			BinopExp b = (BinopExp) rhs;
 | 
			
		||||
			if ( precedence(op) > precedence(b.op)  )
 | 
			
		||||
				return binaryexp( unaryexp(op, b.lhs), b.op, b.rhs );
 | 
			
		||||
		}
 | 
			
		||||
		return new UnopExp(op, rhs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Exp binaryexp(Exp lhs, int op, Exp rhs) {
 | 
			
		||||
		if ( lhs instanceof UnopExp ) {
 | 
			
		||||
			UnopExp u = (UnopExp) lhs;
 | 
			
		||||
			if ( precedence(op) > precedence(u.op) )
 | 
			
		||||
				return unaryexp( u.op, binaryexp( u.rhs, op, rhs ) );
 | 
			
		||||
		}
 | 
			
		||||
		// TODO: cumulate string concatenations together
 | 
			
		||||
		// TODO: constant folding
 | 
			
		||||
		if ( lhs instanceof BinopExp ) {
 | 
			
		||||
			BinopExp b = (BinopExp) lhs;
 | 
			
		||||
			if ( (precedence(op) > precedence(b.op)) ||
 | 
			
		||||
				 ((precedence(op) == precedence(b.op)) && isrightassoc(op)) )
 | 
			
		||||
				return binaryexp( b.lhs, b.op, binaryexp( b.rhs, op, rhs ) );
 | 
			
		||||
		}
 | 
			
		||||
		if ( rhs instanceof BinopExp ) {
 | 
			
		||||
			BinopExp b = (BinopExp) rhs;
 | 
			
		||||
			if ( (precedence(op) > precedence(b.op)) ||
 | 
			
		||||
				 ((precedence(op) == precedence(b.op)) && ! isrightassoc(op)) )
 | 
			
		||||
				return binaryexp( binaryexp( lhs, op, b.lhs ), b.op, b.rhs );
 | 
			
		||||
		}
 | 
			
		||||
		return new BinopExp(lhs, op, rhs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static boolean isrightassoc(int op) {
 | 
			
		||||
		switch ( op ) {
 | 
			
		||||
		case Lua.OP_CONCAT:
 | 
			
		||||
		case Lua.OP_POW: return true;
 | 
			
		||||
		default: return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	static int precedence(int op) {
 | 
			
		||||
		switch ( op ) {
 | 
			
		||||
		case Lua.OP_OR: return 0;
 | 
			
		||||
		case Lua.OP_AND: return 1;
 | 
			
		||||
		case Lua.OP_LT: case Lua.OP_GT: case Lua.OP_LE: case Lua.OP_GE: case Lua.OP_NEQ: case Lua.OP_EQ: return 2;
 | 
			
		||||
		case Lua.OP_CONCAT: return 3;
 | 
			
		||||
		case Lua.OP_ADD: case Lua.OP_SUB: return 4;
 | 
			
		||||
		case Lua.OP_MUL: case Lua.OP_DIV: case Lua.OP_MOD: return 5;
 | 
			
		||||
		case Lua.OP_NOT: case Lua.OP_UNM: case Lua.OP_LEN: return 6;
 | 
			
		||||
		case Lua.OP_POW: return 7;
 | 
			
		||||
		default: throw new IllegalStateException("precedence of bad op "+op);
 | 
			
		||||
		}
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	public static Exp anonymousfunction(FuncBody funcbody) {
 | 
			
		||||
		return new AnonFuncDef(funcbody);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** foo */
 | 
			
		||||
	public static NameExp nameprefix(String name) {
 | 
			
		||||
		return new NameExp(name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** ( foo.bar ) */
 | 
			
		||||
	public static ParensExp parensprefix(Exp exp) {
 | 
			
		||||
		return new ParensExp(exp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** foo[exp] */
 | 
			
		||||
	public static IndexExp indexop(PrimaryExp lhs, Exp exp) {
 | 
			
		||||
		return new IndexExp(lhs, exp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** foo.bar */
 | 
			
		||||
	public static FieldExp fieldop(PrimaryExp lhs, String name) {
 | 
			
		||||
		return new FieldExp(lhs, name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** foo(2,3) */
 | 
			
		||||
	public static FuncCall functionop(PrimaryExp lhs, FuncArgs args) {
 | 
			
		||||
		return new FuncCall(lhs, args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** foo:bar(4,5) */
 | 
			
		||||
	public static MethodCall methodop(PrimaryExp lhs, String name, FuncArgs args) {
 | 
			
		||||
		return new MethodCall(lhs, name, args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isvarexp() {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isfunccall() {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isvarargexp() {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	abstract public static class PrimaryExp extends Exp {
 | 
			
		||||
		public boolean isvarexp() {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		public boolean isfunccall() {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	abstract public static class VarExp extends PrimaryExp {
 | 
			
		||||
		public boolean isvarexp() {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		public void markHasAssignment() {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static class NameExp extends VarExp {
 | 
			
		||||
		public final Name name;
 | 
			
		||||
		public NameExp(String name) {
 | 
			
		||||
			this.name = new Name(name);
 | 
			
		||||
		}
 | 
			
		||||
		public void markHasAssignment() {
 | 
			
		||||
			name.variable.hasassignments = true;
 | 
			
		||||
		}
 | 
			
		||||
		public void accept(Visitor visitor) {
 | 
			
		||||
			visitor.visit(this);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static class ParensExp extends PrimaryExp {
 | 
			
		||||
		public final Exp exp;
 | 
			
		||||
		public ParensExp(Exp exp) {
 | 
			
		||||
			this.exp = exp;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public void accept(Visitor visitor) {
 | 
			
		||||
			visitor.visit(this);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static class FieldExp extends VarExp {
 | 
			
		||||
		public final PrimaryExp lhs;
 | 
			
		||||
		public final Name name;
 | 
			
		||||
		public FieldExp(PrimaryExp lhs, String name) {
 | 
			
		||||
			this.lhs = lhs;
 | 
			
		||||
			this.name = new Name(name);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public void accept(Visitor visitor) {
 | 
			
		||||
			visitor.visit(this);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static class IndexExp extends VarExp {
 | 
			
		||||
		public final PrimaryExp lhs;
 | 
			
		||||
		public final Exp exp;
 | 
			
		||||
		public IndexExp(PrimaryExp lhs, Exp exp) {
 | 
			
		||||
			this.lhs = lhs;
 | 
			
		||||
			this.exp = exp;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public void accept(Visitor visitor) {
 | 
			
		||||
			visitor.visit(this);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static class FuncCall extends PrimaryExp {
 | 
			
		||||
		public final PrimaryExp lhs;
 | 
			
		||||
		public final FuncArgs args;
 | 
			
		||||
		
 | 
			
		||||
		public FuncCall(PrimaryExp lhs, FuncArgs args) {
 | 
			
		||||
			this.lhs = lhs;
 | 
			
		||||
			this.args = args;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public boolean isfunccall() {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public void accept(Visitor visitor) {
 | 
			
		||||
			visitor.visit(this);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public boolean isvarargexp() {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static class MethodCall extends FuncCall {
 | 
			
		||||
		public final String name;
 | 
			
		||||
		
 | 
			
		||||
		public MethodCall(PrimaryExp lhs, String name, FuncArgs args) {
 | 
			
		||||
			super(lhs, args);
 | 
			
		||||
			this.name = new String(name);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public boolean isfunccall() {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public void accept(Visitor visitor) {
 | 
			
		||||
			visitor.visit(this);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static class Constant extends Exp {
 | 
			
		||||
		public final LuaValue value;
 | 
			
		||||
		public Constant(LuaValue value) {
 | 
			
		||||
			this.value = value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void accept(Visitor visitor) {
 | 
			
		||||
			visitor.visit(this);
 | 
			
		||||
		}		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static class VarargsExp extends Exp {
 | 
			
		||||
		
 | 
			
		||||
		public void accept(Visitor visitor) {
 | 
			
		||||
			visitor.visit(this);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public boolean isvarargexp() {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static class UnopExp extends Exp {
 | 
			
		||||
		public final int op;
 | 
			
		||||
		public final Exp rhs;
 | 
			
		||||
		public UnopExp(int op, Exp rhs) {
 | 
			
		||||
			this.op = op;
 | 
			
		||||
			this.rhs = rhs;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void accept(Visitor visitor) {
 | 
			
		||||
			visitor.visit(this);
 | 
			
		||||
		}		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static class BinopExp extends Exp {
 | 
			
		||||
		public final Exp lhs,rhs;
 | 
			
		||||
		public final int op;
 | 
			
		||||
		public BinopExp(Exp lhs, int op, Exp rhs) {
 | 
			
		||||
			this.lhs = lhs;
 | 
			
		||||
			this.op = op;
 | 
			
		||||
			this.rhs = rhs;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void accept(Visitor visitor) {
 | 
			
		||||
			visitor.visit(this);
 | 
			
		||||
		}		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static class AnonFuncDef extends Exp {
 | 
			
		||||
		public final FuncBody body;
 | 
			
		||||
		public AnonFuncDef(FuncBody funcbody) {
 | 
			
		||||
			this.body = funcbody;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void accept(Visitor visitor) {
 | 
			
		||||
			visitor.visit(this);
 | 
			
		||||
		}		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,66 +0,0 @@
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
* Copyright (c) 2010 Luaj.org. All rights reserved.
 | 
			
		||||
*
 | 
			
		||||
* 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.
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
package org.luaj.vm2.ast;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.luaj.vm2.LuaString;
 | 
			
		||||
 | 
			
		||||
public class FuncArgs {
 | 
			
		||||
 | 
			
		||||
	public final List<Exp> exps;
 | 
			
		||||
	
 | 
			
		||||
	/** exp1,exp2... */
 | 
			
		||||
	public static FuncArgs explist(List<Exp> explist) {
 | 
			
		||||
		return new FuncArgs(explist);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** {...} */
 | 
			
		||||
	public static FuncArgs tableconstructor(TableConstructor table) {
 | 
			
		||||
		return new FuncArgs(table);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** "mylib" */
 | 
			
		||||
	public static FuncArgs string(LuaString string) {
 | 
			
		||||
		return new FuncArgs(string);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public FuncArgs(List<Exp> exps) {
 | 
			
		||||
		this.exps = exps;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public FuncArgs(LuaString string) {
 | 
			
		||||
		this.exps = new ArrayList<Exp>();
 | 
			
		||||
		this.exps.add( Exp.constant(string) );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public FuncArgs(TableConstructor table) {
 | 
			
		||||
		this.exps = new ArrayList<Exp>();
 | 
			
		||||
		this.exps.add( table );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void accept(Visitor visitor) {
 | 
			
		||||
		visitor.visit(this);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user