/// import { ClassLoader, BootstrapClassLoader } from './ClassLoader'; import { Method } from './methods'; import { ThreadStatus, StackFrameType } from './enums'; import gLong from './gLong'; import JVM from './jvm'; import * as JVMTypes from '../includes/JVMTypes'; import Monitor from './Monitor'; import { default as ThreadPool, Thread } from './threadpool'; /** * Represents a stack frame. */ export interface IStackFrame { /** * Runs or resumes the method, as configured. */ run: (thread: JVMThread) => void; /** * Configures the method to resume after a method call. * @rv The return value from the method call, if applicable. * @rv2 The second return value, which will always be null if applicable. */ scheduleResume: (thread: JVMThread, rv?: any, rv2?: any) => void; /** * Checks if the method can handle the given exception. If so, * configures the stack frame to handle the exception. * @return True if the method can handle the exception. */ scheduleException: (thread: JVMThread, e: JVMTypes.java_lang_Throwable) => boolean; /** * This stack frame's type. */ type: StackFrameType; /** * Retrieve a stack trace frame from this stack trace. If this stack frame * should not be language-visible, return null. */ getStackTraceFrame(): IStackTraceFrame; /** * Retrieve the classloader for this method. */ getLoader(): ClassLoader; } export declare class PreAllocatedStack { private store; private curr; constructor(initialSize: number); push(x: any): void; pushAll(): void; pushWithNull(x: any): void; push6(x: any, y: any, z: any, z1: any, z2: any, z3: any): void; swap(): void; dup(): void; dup2(): void; dup_x1(): void; dup_x2(): void; dup2_x1(): void; pop(): any; pop2(): any; bottom(): any; top(): any; fromTop(n: number): any; sliceFromBottom(n: number): any; sliceFromTop(n: number): any; dropFromTop(n: number): void; sliceAndDropFromTop(n: number): any; getRaw(): any[]; clear(): void; } /** * Represents a stack frame for a bytecode method. */ export declare class BytecodeStackFrame implements IStackFrame { pc: number; locals: any[]; opStack: PreAllocatedStack; returnToThreadLoop: boolean; lockedMethodLock: boolean; method: Method; /** * Constructs a bytecode method's stack frame. * @param method The bytecode method to run. * @param args The arguments to pass to the bytecode method. */ constructor(method: Method, args: any[]); run(thread: JVMThread): void; scheduleResume(thread: JVMThread, rv?: any, rv2?: any): void; /** * Checks if this method can handle the specified exception 'e'. * Returns true if it can, or if it needs to asynchronously resolve some * classes. * * In the latter case, scheduleException will handle rethrowing the exception * in the event that it can't actually handle it. */ scheduleException(thread: JVMThread, e: JVMTypes.java_lang_Throwable): boolean; /** * Returns the classloader for the stack frame. */ getLoader(): ClassLoader; /** * Indicates the type of this stack frame. */ type: StackFrameType; getStackTraceFrame(): IStackTraceFrame; } /** * Represents a native method's stack frame. */ export declare class NativeStackFrame implements IStackFrame { private nativeMethod; method: Method; private args; /** * Constructs a native method's stack frame. * @param method The native method to run. * @param args The arguments to pass to the native method. */ constructor(method: Method, args: any[]); /** * Calls the native method. * NOTE: Should only be called once. */ run(thread: JVMThread): void; /** * N/A */ scheduleResume(thread: JVMThread, rv?: any, rv2?: any): void; /** * Not relevant; the first execution block of a native method will never * receive an exception. */ scheduleException(thread: JVMThread, e: JVMTypes.java_lang_Throwable): boolean; type: StackFrameType; getStackTraceFrame(): IStackTraceFrame; /** * Returns the classloader for the stack frame. */ getLoader(): ClassLoader; } /** * InternalStackFrames are used by the JVM to launch JVM functions that * eventually call back into JavaScript code when they complete or throw a * fatal exception. */ export declare class InternalStackFrame implements IStackFrame { private isException; private val; private cb; /** * @param cb Callback function. Called with an exception if one occurs, or * the return value from the called method, if relevant. */ constructor(cb: (e?: JVMTypes.java_lang_Throwable, rv?: any) => void); run(thread: JVMThread): void; /** * Resumes the JavaScript code that created this stack frame. */ scheduleResume(thread: JVMThread, rv?: any): void; /** * Resumes the JavaScript code that created this stack frame with the given * exception. */ scheduleException(thread: JVMThread, e: JVMTypes.java_lang_Throwable): boolean; type: StackFrameType; getStackTraceFrame(): IStackTraceFrame; getLoader(): ClassLoader; } export interface IStackTraceFrame { method: Method; pc: number; stack: any[]; locals: any[]; } /** * Represents a single JVM thread. */ export declare class JVMThread implements Thread { /** * The current state of this thread, from the JVM level. */ private status; /** * The call stack. */ private stack; /** * Whether or not this thread has been interrupted. It's a JVM thing. */ private interrupted; /** * If the thread is WAITING, BLOCKED, or TIMED_WAITING, this field holds the * monitor that is involved. */ private monitor; private bsCl; private tpool; private jvmThreadObj; private jvm; /** * Initializes a new JVM thread. Starts the thread in the NEW state. */ constructor(jvm: JVM, tpool: ThreadPool, threadObj: JVMTypes.java_lang_Thread); /** * Get the JVM thread object that represents this thread. */ getJVMObject(): JVMTypes.java_lang_Thread; /** * Is this thread a daemon? */ isDaemon(): boolean; /** * Get the priority of this thread. */ getPriority(): number; /** * XXX: Used during bootstrapping to set the first thread's Thread object. */ setJVMObject(obj: JVMTypes.java_lang_Thread): void; /** * Return the reference number for this thread. */ getRef(): number; /** * Check if this thread's interrupted flag is set. */ isInterrupted(): boolean; /** * Returns the currently running method. Returns NULL if stack is empty. */ currentMethod(): Method; /** * Set or unset this thread's interrupted flag. */ setInterrupted(interrupted: boolean): void; /** * Retrieve the bootstrap classloader. */ getBsCl(): BootstrapClassLoader; /** * Get the classloader for the current frame. */ getLoader(): ClassLoader; /** * Imports & initializes the given Java class or classes. Returns the JavaScript * object that represents the class -- e.g. contains static methods * and fields. * * If multiple names are specified, it returns an array of class objects. * * If there is an error resolving or initializing any class, it will * throw an exception without invoking your callback. */ import(name: string, cb: (rv?: T) => void, explicit?: boolean): void; import(names: string[], cb: (rv?: T) => void, explicit?: boolean): void; private _import(name, loader, cb, explicit); /** * Retrieve the JVM instantiation that this thread belongs to. */ getJVM(): JVM; /** * Retrieve the thread pool that this thread belongs to. */ getThreadPool(): ThreadPool; /** * Retrieves the current stack trace. */ getStackTrace(): IStackTraceFrame[]; /** * [DEBUG] Return a printable string of the thread's current stack trace. */ getPrintableStackTrace(): string; /** * The thread's main execution loop. Everything starts here! * * SHOULD ONLY BE INVOKED BY THE SCHEDULER. */ run(): void; /** * [DEBUG] Performs a sanity check on the thread. */ private sanityCheck(); /** * Should only be called by setStatus. * Updates both the JVMThread object and this object. */ private rawSetStatus(newStatus); /** * Transitions the thread from one state to the next. * Contains JVM-specific thread logic. */ setStatus(status: ThreadStatus, monitor?: Monitor): void; /** * Called when a thread finishes executing. */ private exit(); /** * Called when the priority of the thread changes. * Should only be called by java.lang.setPriority0. */ signalPriorityChange(): void; /** * Get the monitor that this thread is waiting or blocked on. */ getMonitorBlock(): Monitor; /** * Get the thread's current state. */ getStatus(): ThreadStatus; /** * Returns from the currently executing method with the given return value. * Used by asynchronous native * * Causes the following state transition: * * RUNNING => RUNNABLE * * RUNNABLE => RUNNABLE * * ASYNC_WAITING => RUNNABLE * * It is not valid to call this method if the thread is in any other state. */ asyncReturn(): void; asyncReturn(rv: number): void; asyncReturn(rv: JVMTypes.java_lang_Object): void; asyncReturn(rv: number, rv2: any): void; asyncReturn(rv: gLong, rv2: any): void; /** * Pops the top stackframe off of the call stack. * WARNING: SHOULD ONLY BE CALLED BY InternalStackFrame.run()! */ framePop(): void; /** * Throws the given JVM exception. Causes the thread to unwind the stack until * it can find a stack frame that can handle the exception. * * Causes the following state transition: * * RUNNING => RUNNABLE * * RUNNABLE => RUNNABLE * * ASYNC_WAITING => RUNNABLE * * Or, if the exception is uncaught, one of the following transitions: * * RUNNING => TERMINATED * * RUNNABLE => TERMINATED * * ASYNC_WAITING => TERMINATED * * It is not valid to call this method if the thread is in any other state. */ throwException(exception: JVMTypes.java_lang_Throwable): void; /** * Construct a new exception object of the given class with the given message. * Convenience function for native JavaScript code. * @param clsName Name of the class (e.g. "Ljava/lang/Throwable;") * @param msg The message to include with the exception. */ throwNewException(clsName: string, msg: string): void; /** * Handles an uncaught exception on a thread. */ handleUncaughtException(exception: JVMTypes.java_lang_Throwable): void; close(): void; } /** * [DEBUG] Stores all of the valid thread transitions. * @todo Any way to make this smaller? * @todo Move into 'debug' module that we NOP out in release builds. */ export declare var validTransitions: { [oldStatus: number]: { [newStatus: number]: string; }; }; export declare var OpcodeLayoutPrinters: { [layoutAtom: number]: (method: Method, code: NodeBuffer, pc: number) => string; }; export declare function annotateOpcode(op: number, method: Method, code: NodeBuffer, pc: number): string;