/*
 * Copyright (C) 2018-2020 Western Digital Corporation or its affiliates
 * Copyright (C) 2017-2018 Wearable, Inc.
 * Copyright (C) 2000-2012 leJOS Contributors
 * Copyright (C) 2000 Jose H. Solorzano and TinyVM Contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 * 
 * This Source Code Form is “Incompatible With Secondary Licenses”,
 * as defined by the Mozilla Public License, v. 2.0.
 */

package org.naniteproject;

import java.util.Iterator;

/**
 * This class provides access to many of the internal structures of the
 * virtual machine. In particular it provides Java level access to the classes,
 * methods fields etc. that make up the currently executing program. These
 * structures are used by the VM to create the in memory program. They are
 * similar to the class file format used by a standard JVM, but with much of the
 * detail stripped away.
 *
 * The structures fall into two general types. Those that are contained within
 * Java objects (and so can be made directly available to a user program) and
 * those that are simply raw data. To allow access to the second type of data
 * we create Java objects with a copy of the data in them. In some cases we
 * also do this even for tables/etc. that are available as objects as wrapping
 * the class in this way may make it easier to manipulate.
 * 
 * NOTE: Many of the structures in this file are a direct mapping to internal
 * data within the VM. Changes to the VM structures must also be reflected here.
 * Take care when editing this code to ensure that changes do not modify this
 * mapping. Also many of the tables use byte fields that really should be
 * treated as unsigned values. We have to take great care when converting these
 * to integers.
 */
public class VM {
    /**
     * Return the class number of the specified class.
     * @param cla The class whose number is to be returned.
     * @return The class number of the specified class.
     */
    public native static int getClassNumber(Class<?> cla);

    /**
     * Native method to call the firmware exception handler. This will display
     * the exception details and exit the program.
     * @param exception exception class with details of the current exception
     * @param method Method number of the method in which the exception occurred 
     * @param pc PC at which the exception occurred
     */
    public static native void firmwareExceptionHandler(Throwable exception, int method, int pc);
    
    /**
     * Native method to create the stack trace in a compact internal form. This
     * is currently an array of integers with one int per stack frame. The high
     * 16 bits contains the method number, the low 16 bits contains the PC
     * within the method.
     * @param thread The thread to create the stack for.
     * @param ignore Ignore stack frames that have a this which matches ignore.
     * @return An array of stack frame details.
     */
    public static native int[] createStackTrace(Thread thread, Object ignore);
    
    /**
     * Suspend a thread. This places the specified thread into a suspended
     * state. If thread is null all threads except for the current thread will
     * be suspended.
     * @param thread The thread to suspend
     */
    public native static final void suspendThread(Object thread);
    
    /**
     * Resume a thread. A suspended thread will be resumed to it's previous
     * state. If thread is null all suspended threads will be resumed.
     * @param thread The thread to resume
     */
    public native static final void resumeThread(Object thread);

    /**
     * Creates a new array of the given type with the given size.
     *
     * @param array The array type to create
     * @param size The size of the new array
     * @return The newly created array
     */
    public native static final Object newArrayFromInstance(Object array, int size);
}
