MalikInterrupt.java

Переключить прокрутку окна
Загрузить этот исходный код

/*
	Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
	и других спецификаций для функционирования компактных приложений на языке
	Java (мидлетов) в среде программного обеспечения Малик Эмулятор.

	Copyright © 2016, 2019 Малик Разработчик

	Это свободная программа: вы можете перераспространять ее и/или изменять
	ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
	в каком она была опубликована Фондом свободного программного обеспечения;
	либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

	Эта программа распространяется в надежде, что она будет полезной,
	но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
	или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
	общественной лицензии GNU.

	Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
	вместе с этой программой. Если это не так, см.
	<https://www.gnu.org/licenses/>.
*/


package java.lang;

public final class MalikInterrupt extends Object
{
	private static final int TABLE_ADDRESS = 0x00800000;

	private static short[] BUSY;

	public static void invoke(int number) throws Throwable
	{
		int error;
		if(number < 0x00 || number > 0xff)
		{
			throw new IllegalArgumentException("MalikInterrupt.invoke: аргумент number выходит из диапазона.");
		}
		if(number <= 0x22)
		{
			throw new SecurityException("MalikInterrupt.invoke: невозможно вызвать системный обработчик прерывания.");
		}
		error = 0;
		synchronized(BUSY)
		{
			label0:
			{
				Object handler;
				if((handler = getHandler(number)) == null)
				{
					error = 1;
					break label0;
				}
				if(!(handler instanceof InterruptVoid) || getEntry(number) != handler.getClass().getInterfaceMethodEntryPoint(MalikSystem.getClassInstance("Ljava/lang/InterruptVoid;"), 0))
				{
					error = 2;
					break label0;
				}
				BUSY[number]++;
			}
		}
		switch(error)
		{
		case 1:
			throw new NullPointerException("MalikInterrupt.invoke: обработчик прерывания не задан.");
		case 2:
			throw new ClassCastException("MalikInterrupt.invoke: обработчик прерывания не задан как InterruptVoid.");
		}
		try
		{
			MalikSystem.interrupt(number);
		}
		finally
		{
			exit(number);
		}
	}

	public static void invoke(int number, int argument) throws Throwable
	{
		int error;
		if(number < 0x00 || number > 0xff)
		{
			throw new IllegalArgumentException("MalikInterrupt.invoke: аргумент number выходит из диапазона.");
		}
		if(number <= 0x22)
		{
			throw new SecurityException("MalikInterrupt.invoke: невозможно вызвать системный обработчик прерывания.");
		}
		error = 0;
		synchronized(BUSY)
		{
			label0:
			{
				Object handler;
				if((handler = getHandler(number)) == null)
				{
					error = 1;
					break label0;
				}
				if(!(handler instanceof InterruptInt) || getEntry(number) != handler.getClass().getInterfaceMethodEntryPoint(MalikSystem.getClassInstance("Ljava/lang/InterruptInt;"), 0))
				{
					error = 2;
					break label0;
				}
				BUSY[number]++;
			}
		}
		switch(error)
		{
		case 1:
			throw new NullPointerException("MalikInterrupt.invoke: обработчик прерывания не задан.");
		case 2:
			throw new ClassCastException("MalikInterrupt.invoke: обработчик прерывания не задан как InterruptInt.");
		}
		try
		{
			MalikSystem.interrupt(argument, number);
		}
		finally
		{
			exit(number);
		}
	}

	public static void invoke(int number, long argument) throws Throwable
	{
		int error;
		if(number < 0x00 || number > 0xff)
		{
			throw new IllegalArgumentException("MalikInterrupt.invoke: аргумент number выходит из диапазона.");
		}
		if(number <= 0x22)
		{
			throw new SecurityException("MalikInterrupt.invoke: невозможно вызвать системный обработчик прерывания.");
		}
		error = 0;
		synchronized(BUSY)
		{
			label0:
			{
				Object handler;
				if((handler = getHandler(number)) == null)
				{
					error = 1;
					break label0;
				}
				if(!(handler instanceof InterruptLong) || getEntry(number) != handler.getClass().getInterfaceMethodEntryPoint(MalikSystem.getClassInstance("Ljava/lang/InterruptLong;"), 0))
				{
					error = 2;
					break label0;
				}
				BUSY[number]++;
			}
		}
		switch(error)
		{
		case 1:
			throw new NullPointerException("MalikInterrupt.invoke: обработчик прерывания не задан.");
		case 2:
			throw new ClassCastException("MalikInterrupt.invoke: обработчик прерывания не задан как InterruptLong.");
		}
		try
		{
			MalikSystem.interrupt(argument, number);
		}
		finally
		{
			exit(number);
		}
	}

	public static void invoke(int number, Object argument) throws Throwable
	{
		int error;
		if(number < 0x00 || number > 0xff)
		{
			throw new IllegalArgumentException("MalikInterrupt.invoke: аргумент number выходит из диапазона.");
		}
		if(number <= 0x22)
		{
			throw new SecurityException("MalikInterrupt.invoke: невозможно вызвать системный обработчик прерывания.");
		}
		error = 0;
		synchronized(BUSY)
		{
			label0:
			{
				Object handler;
				if((handler = getHandler(number)) == null)
				{
					error = 1;
					break label0;
				}
				if(!(handler instanceof InterruptObject) || getEntry(number) != handler.getClass().getInterfaceMethodEntryPoint(MalikSystem.getClassInstance("Ljava/lang/InterruptObject;"), 0))
				{
					error = 2;
					break label0;
				}
				BUSY[number]++;
			}
		}
		switch(error)
		{
		case 1:
			throw new NullPointerException("MalikInterrupt.invoke: обработчик прерывания не задан.");
		case 2:
			throw new ClassCastException("MalikInterrupt.invoke: обработчик прерывания не задан как InterruptObject.");
		}
		try
		{
			MalikSystem.interrupt(argument, number);
		}
		finally
		{
			exit(number);
		}
	}

	public static void register(int number, InterruptVoid handler)
	{
		init();
		if(number < 0x00 || number > 0xff)
		{
			throw new IllegalArgumentException("MalikInterrupt.register: аргумент number выходит из диапазона.");
		}
		if(number <= 0x22 && getHandler(number) != null)
		{
			throw new SecurityException("MalikInterrupt.register: невозможно переписать системный обработчик прерывания.");
		}
		if(number <= 0x22)
		{
			register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptVoid;"));
			return;
		}
		synchronized(BUSY)
		{
			while(BUSY[number] != 0)
			{
				try
				{
					BUSY.wait();
				}
				catch(InterruptedException e)
				{
					e.printRealStackTrace();
				}
			}
			register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptVoid;"));
		}
	}

	public static void register(int number, InterruptInt handler)
	{
		init();
		if(number < 0x00 || number > 0xff)
		{
			throw new IllegalArgumentException("MalikInterrupt.register: аргумент number выходит из диапазона.");
		}
		if(number <= 0x22 && getHandler(number) != null)
		{
			throw new SecurityException("MalikInterrupt.register: невозможно переписать системный обработчик прерывания.");
		}
		if(number <= 0x22)
		{
			register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptInt;"));
			return;
		}
		synchronized(BUSY)
		{
			while(BUSY[number] != 0)
			{
				try
				{
					BUSY.wait();
				}
				catch(InterruptedException e)
				{
					e.printRealStackTrace();
				}
			}
			register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptInt;"));
		}
	}

	public static void register(int number, InterruptLong handler)
	{
		init();
		if(number < 0x00 || number > 0xff)
		{
			throw new IllegalArgumentException("MalikInterrupt.register: аргумент number выходит из диапазона.");
		}
		if(number <= 0x22 && getHandler(number) != null)
		{
			throw new SecurityException("MalikInterrupt.register: невозможно переписать системный обработчик прерывания.");
		}
		if(number <= 0x22)
		{
			register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptLong;"));
			return;
		}
		synchronized(BUSY)
		{
			while(BUSY[number] != 0)
			{
				try
				{
					BUSY.wait();
				}
				catch(InterruptedException e)
				{
					e.printRealStackTrace();
				}
			}
			register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptLong;"));
		}
	}

	public static void register(int number, InterruptObject handler)
	{
		init();
		if(number < 0x00 || number > 0xff)
		{
			throw new IllegalArgumentException("MalikInterrupt.register: аргумент number выходит из диапазона.");
		}
		if(number <= 0x22 && getHandler(number) != null)
		{
			throw new SecurityException("MalikInterrupt.register: невозможно переписать системный обработчик прерывания.");
		}
		if(number <= 0x22)
		{
			register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptObject;"));
			return;
		}
		synchronized(BUSY)
		{
			while(BUSY[number] != 0)
			{
				try
				{
					BUSY.wait();
				}
				catch(InterruptedException e)
				{
					e.printRealStackTrace();
				}
			}
			register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptObject;"));
		}
	}

	public static void remove(int number)
	{
		init();
		if(number < 0x00 || number > 0xff)
		{
			throw new IllegalArgumentException("MalikInterrupt.remove: аргумент number выходит из диапазона.");
		}
		if(number <= 0x22 && getHandler(number) != null)
		{
			throw new SecurityException("MalikInterrupt.remove: невозможно переписать системный обработчик прерывания.");
		}
		if(number <= 0x22)
		{
			register(number, null, null);
			return;
		}
		synchronized(BUSY)
		{
			while(BUSY[number] != 0)
			{
				try
				{
					BUSY.wait();
				}
				catch(InterruptedException e)
				{
					e.printRealStackTrace();
				}
			}
			register(number, null, null);
		}
	}

	public static void enable(boolean enabled)
	{
		try
		{
			MalikSystem.interrupt(enabled ? 1 : 0, 0x22);
		}
		catch(Throwable e)
		{
		}
	}

	public static void enable()
	{
		try
		{
			MalikSystem.interrupt(1, 0x22);
		}
		catch(Throwable e)
		{
		}
	}

	public static void disable()
	{
		try
		{
			MalikSystem.interrupt(0, 0x22);
		}
		catch(Throwable e)
		{
		}
	}

	public static boolean enabled()
	{
		boolean result = false;
		try
		{
			MalikSystem.interrupt(MalikSystem.getLocalVariableAddress(result), 0x21);
		}
		catch(Throwable t)
		{
		}
		return result;
	}

	private static void init()
	{
		if(BUSY == null)
		{
			BUSY = new short[0x0100];
		}
	}

	private static void exit(int number)
	{
		synchronized(BUSY)
		{
			if(--BUSY[number] == 0)
			{
				BUSY.notifyAll();
			}
		}
	}

	private static void register(int number, Object handler, Class type)
	{
		int entry = handler != null ? handler.getClass().getInterfaceMethodEntryPoint(type, 0) : 0;
		int address = TABLE_ADDRESS + (number << 3);
		MalikSystem.setIntAt(address, 0);
		if(entry == 0)
		{
			MalikSystem.setObjectAt(address + 4, null);
			return;
		}
		MalikSystem.setObjectAt(address + 4, handler);
		MalikSystem.setIntAt(address, entry);
	}

	private static int getEntry(int number)
	{
		return MalikSystem.getIntAt(TABLE_ADDRESS + (number << 3));
	}

	private static Object getHandler(int number)
	{
		return MalikSystem.getObjectAt((TABLE_ADDRESS + 4) + (number << 3));
	}


	private MalikInterrupt()
	{
	}
}