/*
 * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
/*
 * eventFilter
 *
 * This module handles event filteration and the enabling/disabling
 * of the corresponding events. Used for filters on JDI EventRequests
 * and also internal requests.  Our data is in a private hidden section
 * of the HandlerNode's data.  See comment for enclosing
 * module eventHandler.
 */

#include "util.h"
#include "eventFilter.h"
#include "eventFilterRestricted.h"
#include "eventHandlerRestricted.h"
#include "stepControl.h"
#include "threadControl.h"
#include "SDE.h"

typedef struct ClassFilter {
    jclass clazz;
} ClassFilter;

typedef struct LocationFilter {
    jclass clazz;
    jmethodID method;
    jlocation location;
} LocationFilter;

typedef struct ThreadFilter {
    jthread thread;
} ThreadFilter;

typedef struct CountFilter {
    jint count;
} CountFilter;

typedef struct ConditionalFilter {
    jint exprID;
} ConditionalFilter;

typedef struct FieldFilter {
    jclass clazz;
    jfieldID field;
} FieldFilter;

typedef struct ExceptionFilter {
    jclass exception;
    jboolean caught;
    jboolean uncaught;
} ExceptionFilter;

typedef struct InstanceFilter {
    jobject instance;
} InstanceFilter;

typedef struct StepFilter {
    jint size;
    jint depth;
    jthread thread;
} StepFilter;

typedef struct MatchFilter {
    char *classPattern;
} MatchFilter;

typedef struct SourceNameFilter {
    char *sourceNamePattern;
} SourceNameFilter;

typedef struct Filter_ {
    jbyte modifier;
    union {
        struct ClassFilter ClassOnly;
        struct LocationFilter LocationOnly;
        struct ThreadFilter ThreadOnly;
        struct CountFilter Count;
        struct ConditionalFilter Conditional;
        struct FieldFilter FieldOnly;
        struct ExceptionFilter ExceptionOnly;
        struct InstanceFilter InstanceOnly;
        struct StepFilter Step;
        struct MatchFilter ClassMatch;
        struct MatchFilter ClassExclude;
        struct SourceNameFilter SourceNameOnly;
    } u;
} Filter;

/* The filters array is allocated to the specified filterCount.
 * Theoretically, some compiler could do range checking on this
 * array - so, we define it to have a ludicrously large size so
 * that this range checking won't get upset.
 *
 * The actual allocated number of bytes is computed using the
 * offset of "filters" and so is not effected by this number.
 */
#define MAX_FILTERS 10000

typedef struct EventFilters_ {
    jint filterCount;
    Filter filters[MAX_FILTERS];
} EventFilters;

typedef struct EventFilterPrivate_HandlerNode_ {
    EventHandlerRestricted_HandlerNode   not_for_us;
    EventFilters                         ef;
} EventFilterPrivate_HandlerNode;

/**
 * The following macros extract filter info (EventFilters) from private
 * data at the end of a HandlerNode
 */
#define EVENT_FILTERS(node) (&(((EventFilterPrivate_HandlerNode*)(void*)node)->ef))
#define FILTER_COUNT(node)  (EVENT_FILTERS(node)->filterCount)
#define FILTERS_ARRAY(node) (EVENT_FILTERS(node)->filters)
#define FILTER(node,index)  ((FILTERS_ARRAY(node))[index])
#define NODE_EI(node)          (node->ei)

/***** filter set-up / destruction *****/

/**
 * Allocate a HandlerNode.
 * We do it because eventHandler doesn't know how big to make it.
 */
HandlerNode *
eventFilterRestricted_alloc(jint filterCount)
{
    /*LINTED*/
    size_t size = offsetof(EventFilterPrivate_HandlerNode, ef) +
                  offsetof(EventFilters, filters) +
                  (filterCount * (int)sizeof(Filter));
    HandlerNode *node = jvmtiAllocate((jint)size);

    if (node != NULL) {
        int i;
        Filter *filter;

        (void)memset(node, 0, size);

        FILTER_COUNT(node) = filterCount;

        /* Initialize all modifiers
         */
        for (i = 0, filter = FILTERS_ARRAY(node);
                                    i < filterCount;
                                    i++, filter++) {
            filter->modifier = JDWP_REQUEST_NONE;
        }
    }

    return node;
}

/**
 * Free up global refs held by the filter.
 * free things up at the JNI level if needed.
 */
static jvmtiError
clearFilters(HandlerNode *node)
{
    JNIEnv *env = getEnv();
    jint i;
    jvmtiError error = JVMTI_ERROR_NONE;
    Filter *filter = FILTERS_ARRAY(node);

    for (i = 0; i < FILTER_COUNT(node); ++i, ++filter) {
        switch (filter->modifier) {
            case JDWP_REQUEST_MODIFIER(ThreadOnly):
                if ( filter->u.ThreadOnly.thread != NULL ) {
                    tossGlobalRef(env, &(filter->u.ThreadOnly.thread));
                }
                break;
            case JDWP_REQUEST_MODIFIER(LocationOnly):
                tossGlobalRef(env, &(filter->u.LocationOnly.clazz));
                break;
            case JDWP_REQUEST_MODIFIER(FieldOnly):
                tossGlobalRef(env, &(filter->u.FieldOnly.clazz));
                break;
            case JDWP_REQUEST_MODIFIER(ExceptionOnly):
                if ( filter->u.ExceptionOnly.exception != NULL ) {
                    tossGlobalRef(env, &(filter->u.ExceptionOnly.exception));
                }
                break;
            case JDWP_REQUEST_MODIFIER(InstanceOnly):
                if ( filter->u.InstanceOnly.instance != NULL ) {
                    tossGlobalRef(env, &(filter->u.InstanceOnly.instance));
                }
                break;
            case JDWP_REQUEST_MODIFIER(ClassOnly):
                tossGlobalRef(env, &(filter->u.ClassOnly.clazz));
                break;
            case JDWP_REQUEST_MODIFIER(ClassMatch):
                jvmtiDeallocate(filter->u.ClassMatch.classPattern);
                break;
            case JDWP_REQUEST_MODIFIER(ClassExclude):
                jvmtiDeallocate(filter->u.ClassExclude.classPattern);
                break;
            case JDWP_REQUEST_MODIFIER(Step): {
                jthread thread = filter->u.Step.thread;
                error = stepControl_endStep(thread);
                if (error == JVMTI_ERROR_NONE) {
                    tossGlobalRef(env, &(filter->u.Step.thread));
                }
                break;
            }
        }
    }
    if (error == JVMTI_ERROR_NONE) {
        FILTER_COUNT(node) = 0; /* blast so we don't clear again */
    }

    return error;
}


/***** filtering *****/

/*
 * Match a string against a wildcard
 * string pattern.
 */
static jboolean
patternStringMatch(char *classname, const char *pattern)
{
    int pattLen;
    int compLen;
    char *start;
    int offset;

    if ( pattern==NULL || classname==NULL ) {
        return JNI_FALSE;
    }
    pattLen = (int)strlen(pattern);

    if ((pattern[0] != '*') && (pattern[pattLen-1] != '*')) {
        /* An exact match is required when there is no *: bug 4331522 */
        return strcmp(pattern, classname) == 0;
    } else {
        compLen = pattLen - 1;
        offset = (int)strlen(classname) - compLen;
        if (offset < 0) {
            return JNI_FALSE;
        } else {
            if (pattern[0] == '*') {
                pattern++;
                start = classname + offset;
            }  else {
                start = classname;
            }
            return strncmp(pattern, start, compLen) == 0;
        }
    }
}

/* Return the object instance in which the event occurred */
/* Return NULL if static or if an error occurs */
static jobject
eventInstance(EventInfo *evinfo)
{
    jobject     object          = NULL;
    jthread     thread          ;
    jmethodID   method          ;
    jint        modifiers       = 0;
    jvmtiError  error;

    switch (evinfo->ei) {
        case EI_SINGLE_STEP:
        case EI_BREAKPOINT:
        case EI_FRAME_POP:
        case EI_METHOD_ENTRY:
        case EI_METHOD_EXIT:
        case EI_EXCEPTION:
        case EI_EXCEPTION_CATCH:
        case EI_MONITOR_CONTENDED_ENTER:
        case EI_MONITOR_CONTENDED_ENTERED:
        case EI_MONITOR_WAIT:
        case EI_MONITOR_WAITED:
            thread      = evinfo->thread;
            method      = evinfo->method;
            break;
        case EI_FIELD_ACCESS:
        case EI_FIELD_MODIFICATION:
            object = evinfo->object;
            return object;
        default:
            return object; /* NULL */
    }

    error = methodModifiers(method, &modifiers);

    /* fail if error or static (0x8) */
    if (error == JVMTI_ERROR_NONE && thread!=NULL && (modifiers & 0x8) == 0) {
        FrameNumber fnum            = 0;
        /* get slot zero object "this" */
        error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalObject)
                    (gdata->jvmti, thread, fnum, 0, &object);
        if (error != JVMTI_ERROR_NONE)
            object = NULL;
    }

    return object;
}

/*
 * Determine if this event is interesting to this handler.
 * Do so by checking each of the handler's filters.
 * Return false if any of the filters fail,
 * true if the handler wants this event.
 * Anyone modifying this function should check
 * eventFilterRestricted_passesUnloadFilter and
 * eventFilter_predictFiltering as well.
 *
 * If shouldDelete is returned true, a count filter has expired
 * and the corresponding node should be deleted.
 */
jboolean
eventFilterRestricted_passesFilter(JNIEnv *env,
                                   char *classname,
                                   EventInfo *evinfo,
                                   HandlerNode *node,
                                   jboolean *shouldDelete)
{
    jthread thread;
    jclass clazz;
    jmethodID method;
    Filter *filter = FILTERS_ARRAY(node);
    int i;

    *shouldDelete = JNI_FALSE;
    thread = evinfo->thread;
    clazz = evinfo->clazz;
    method = evinfo->method;

    /*
     * Suppress most events if they happen in debug threads
     */
    if ((evinfo->ei != EI_CLASS_PREPARE) &&
        (evinfo->ei != EI_GC_FINISH) &&
        (evinfo->ei != EI_CLASS_LOAD) &&
        threadControl_isDebugThread(thread)) {
        return JNI_FALSE;
    }

    for (i = 0; i < FILTER_COUNT(node); ++i, ++filter) {
        switch (filter->modifier) {
            case JDWP_REQUEST_MODIFIER(ThreadOnly):
                if (!isSameObject(env, thread, filter->u.ThreadOnly.thread)) {
                    return JNI_FALSE;
                }
                break;

            case JDWP_REQUEST_MODIFIER(ClassOnly):
                /* Class filters catch events in the specified
                 * class and any subclass/subinterface.
                 */
                if (!JNI_FUNC_PTR(env,IsAssignableFrom)(env, clazz,
                               filter->u.ClassOnly.clazz)) {
                    return JNI_FALSE;
                }
                break;

            /* This is kinda cheating assumming the event
             * fields will be in the same locations, but it is
             * true now.
             */
            case JDWP_REQUEST_MODIFIER(LocationOnly):
                if  (evinfo->method !=
                          filter->u.LocationOnly.method ||
                     evinfo->location !=
                          filter->u.LocationOnly.location ||
                     !isSameObject(env, clazz, filter->u.LocationOnly.clazz)) {
                    return JNI_FALSE;
                }
                break;

            case JDWP_REQUEST_MODIFIER(FieldOnly):
                /* Field watchpoints can be triggered from the
                 * declared class or any subclass/subinterface.
                 */
                if ((evinfo->u.field_access.field !=
                     filter->u.FieldOnly.field) ||
                    !isSameObject(env, evinfo->u.field_access.field_clazz,
                               filter->u.FieldOnly.clazz)) {
                    return JNI_FALSE;
                }
                break;

            case JDWP_REQUEST_MODIFIER(ExceptionOnly):
                /* do we want caught/uncaught exceptions */
                if (!((evinfo->u.exception.catch_clazz == NULL)?
                      filter->u.ExceptionOnly.uncaught :
                      filter->u.ExceptionOnly.caught)) {
                    return JNI_FALSE;
                }

                /* do we care about exception class */
                if (filter->u.ExceptionOnly.exception != NULL) {
                    jclass exception = evinfo->object;

                    /* do we want this exception class */
                    if (!JNI_FUNC_PTR(env,IsInstanceOf)(env, exception,
                            filter->u.ExceptionOnly.exception)) {
                        return JNI_FALSE;
                    }
                }
                break;

            case JDWP_REQUEST_MODIFIER(InstanceOnly): {
                jobject eventInst = eventInstance(evinfo);
                jobject filterInst = filter->u.InstanceOnly.instance;
                /* if no error and doesn't match, don't pass
                 * filter
                 */
                if (eventInst != NULL &&
                      !isSameObject(env, eventInst, filterInst)) {
                    return JNI_FALSE;
                }
                break;
            }
            case JDWP_REQUEST_MODIFIER(Count): {
                JDI_ASSERT(filter->u.Count.count > 0);
                if (--filter->u.Count.count > 0) {
                    return JNI_FALSE;
                }
                *shouldDelete = JNI_TRUE;
                break;
            }

            case JDWP_REQUEST_MODIFIER(Conditional):
/***
                if (...  filter->u.Conditional.exprID ...) {
                    return JNI_FALSE;
                }
***/
                break;

        case JDWP_REQUEST_MODIFIER(ClassMatch): {
            if (!patternStringMatch(classname,
                       filter->u.ClassMatch.classPattern)) {
                return JNI_FALSE;
            }
            break;
        }

        case JDWP_REQUEST_MODIFIER(ClassExclude): {
            if (patternStringMatch(classname,
                      filter->u.ClassExclude.classPattern)) {
                return JNI_FALSE;
            }
            break;
        }

        case JDWP_REQUEST_MODIFIER(Step):
                if (!isSameObject(env, thread, filter->u.Step.thread)) {
                    return JNI_FALSE;
                }
                if (!stepControl_handleStep(env, thread, clazz, method)) {
                    return JNI_FALSE;
                }
                break;

          case JDWP_REQUEST_MODIFIER(SourceNameMatch): {
              char* desiredNamePattern = filter->u.SourceNameOnly.sourceNamePattern;
              if (!searchAllSourceNames(env, clazz,
                           desiredNamePattern) == 1) {
                  /* The name isn't in the SDE; try the sourceName in the ref
                   * type
                   */
                  char *sourceName = 0;
                  jvmtiError error = JVMTI_FUNC_PTR(gdata->jvmti,GetSourceFileName)
                                            (gdata->jvmti, clazz, &sourceName);
                  if (error == JVMTI_ERROR_NONE) {
                      if (sourceName == 0 || !patternStringMatch(sourceName, desiredNamePattern)) {
                        /* We have no match */
                        jvmtiDeallocate(sourceName);
                        return JNI_FALSE;
                      }
                  }
                  jvmtiDeallocate(sourceName);
              }
              break;
          }

        default:
            EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"Invalid filter modifier");
            return JNI_FALSE;
        }
    }
    return JNI_TRUE;
}

/* Determine if this event is interesting to this handler.  Do so
 * by checking each of the handler's filters.  Return false if any
 * of the filters fail, true if the handler wants this event.
 * Special version of filter for unloads since they don't have an
 * event structure or a jclass.
 *
 * If shouldDelete is returned true, a count filter has expired
 * and the corresponding node should be deleted.
 */
jboolean
eventFilterRestricted_passesUnloadFilter(JNIEnv *env,
                                         char *classname,
                                         HandlerNode *node,
                                         jboolean *shouldDelete)
{
    Filter *filter = FILTERS_ARRAY(node);
    int i;

    *shouldDelete = JNI_FALSE;
    for (i = 0; i < FILTER_COUNT(node); ++i, ++filter) {
        switch (filter->modifier) {

            case JDWP_REQUEST_MODIFIER(Count): {
                JDI_ASSERT(filter->u.Count.count > 0);
                if (--filter->u.Count.count > 0) {
                    return JNI_FALSE;
                }
                *shouldDelete = JNI_TRUE;
                break;
            }

            case JDWP_REQUEST_MODIFIER(ClassMatch): {
                if (!patternStringMatch(classname,
                        filter->u.ClassMatch.classPattern)) {
                    return JNI_FALSE;
                }
                break;
            }

            case JDWP_REQUEST_MODIFIER(ClassExclude): {
                if (patternStringMatch(classname,
                       filter->u.ClassExclude.classPattern)) {
                    return JNI_FALSE;
                }
                break;
            }

            default:
                EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"Invalid filter modifier");
                return JNI_FALSE;
        }
    }
    return JNI_TRUE;
}

/**
 * This function returns true only if it is certain that
 * all events for the given node in the given stack frame will
 * be filtered. It is used to optimize stepping. (If this
 * function returns true the stepping algorithm does not
 * have to step through every instruction in this stack frame;
 * instead, it can use more efficient method entry/exit
 * events.
 */
jboolean
eventFilter_predictFiltering(HandlerNode *node, jclass clazz, char *classname)
{
    JNIEnv     *env;
    jboolean    willBeFiltered;
    Filter     *filter;
    jboolean    done;
    int         count;
    int         i;

    willBeFiltered = JNI_FALSE;
    env            = NULL;
    filter         = FILTERS_ARRAY(node);
    count          = FILTER_COUNT(node);
    done           = JNI_FALSE;

    for (i = 0; (i < count) && (!done); ++i, ++filter) {
        switch (filter->modifier) {
            case JDWP_REQUEST_MODIFIER(ClassOnly):
                if ( env==NULL ) {
                    env = getEnv();
                }
                if (!JNI_FUNC_PTR(env,IsAssignableFrom)(env, clazz,
                                 filter->u.ClassOnly.clazz)) {
                    willBeFiltered = JNI_TRUE;
                    done = JNI_TRUE;
                }
                break;

            case JDWP_REQUEST_MODIFIER(Count): {
                /*
                 * If preceeding filters have determined that events will
                 * be filtered out, that is fine and we won't get here.
                 * However, the count must be decremented - even if
                 * subsequent filters will filter these events.  We
                 * thus must end now unable to predict
                 */
                done = JNI_TRUE;
                break;
            }

            case JDWP_REQUEST_MODIFIER(ClassMatch): {
                if (!patternStringMatch(classname,
                        filter->u.ClassMatch.classPattern)) {
                    willBeFiltered = JNI_TRUE;
                    done = JNI_TRUE;
                }
                break;
            }

            case JDWP_REQUEST_MODIFIER(ClassExclude): {
                if (patternStringMatch(classname,
                       filter->u.ClassExclude.classPattern)) {
                    willBeFiltered = JNI_TRUE;
                    done = JNI_TRUE;
                }
                break;
            }
        }
    }

    return willBeFiltered;
}

/**
 * Determine if the given breakpoint node is in the specified class.
 */
jboolean
eventFilterRestricted_isBreakpointInClass(JNIEnv *env, jclass clazz,
                                          HandlerNode *node)
{
    Filter *filter = FILTERS_ARRAY(node);
    int i;

    for (i = 0; i < FILTER_COUNT(node); ++i, ++filter) {
        switch (filter->modifier) {
            case JDWP_REQUEST_MODIFIER(LocationOnly):
                return isSameObject(env, clazz, filter->u.LocationOnly.clazz);
        }
    }
    return JNI_TRUE; /* should never come here */
}

/***** filter set-up *****/

jvmtiError
eventFilter_setConditionalFilter(HandlerNode *node, jint index,
                                 jint exprID)
{
    ConditionalFilter *filter = &FILTER(node, index).u.Conditional;
    if (index >= FILTER_COUNT(node)) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }
    FILTER(node, index).modifier = JDWP_REQUEST_MODIFIER(Conditional);
    filter->exprID = exprID;
    return JVMTI_ERROR_NONE;
}

jvmtiError
eventFilter_setCountFilter(HandlerNode *node, jint index,
                           jint count)
{
    CountFilter *filter = &FILTER(node, index).u.Count;
    if (index >= FILTER_COUNT(node)) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }
    if (count <= 0) {
        return JDWP_ERROR(INVALID_COUNT);
    } else {
        FILTER(node, index).modifier = JDWP_REQUEST_MODIFIER(Count);
        filter->count = count;
        return JVMTI_ERROR_NONE;
    }
}

jvmtiError
eventFilter_setThreadOnlyFilter(HandlerNode *node, jint index,
                                jthread thread)
{
    JNIEnv *env = getEnv();
    ThreadFilter *filter = &FILTER(node, index).u.ThreadOnly;
    if (index >= FILTER_COUNT(node)) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }
    if (NODE_EI(node) == EI_GC_FINISH) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }

    /* Create a thread ref that will live beyond */
    /* the end of this call */
    saveGlobalRef(env, thread, &(filter->thread));
    FILTER(node, index).modifier = JDWP_REQUEST_MODIFIER(ThreadOnly);
    return JVMTI_ERROR_NONE;
}

jvmtiError
eventFilter_setLocationOnlyFilter(HandlerNode *node, jint index,
                                  jclass clazz, jmethodID method,
                                  jlocation location)
{
    JNIEnv *env = getEnv();
    LocationFilter *filter = &FILTER(node, index).u.LocationOnly;
    if (index >= FILTER_COUNT(node)) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }
    if ((NODE_EI(node) != EI_BREAKPOINT) &&
        (NODE_EI(node) != EI_FIELD_ACCESS) &&
        (NODE_EI(node) != EI_FIELD_MODIFICATION) &&
        (NODE_EI(node) != EI_SINGLE_STEP) &&
        (NODE_EI(node) != EI_EXCEPTION)) {

        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }

    /* Create a class ref that will live beyond */
    /* the end of this call */
    saveGlobalRef(env, clazz, &(filter->clazz));
    FILTER(node, index).modifier = JDWP_REQUEST_MODIFIER(LocationOnly);
    filter->method = method;
    filter->location = location;
    return JVMTI_ERROR_NONE;
}

jvmtiError
eventFilter_setFieldOnlyFilter(HandlerNode *node, jint index,
                               jclass clazz, jfieldID field)
{
    JNIEnv *env = getEnv();
    FieldFilter *filter = &FILTER(node, index).u.FieldOnly;
    if (index >= FILTER_COUNT(node)) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }
    if ((NODE_EI(node) != EI_FIELD_ACCESS) &&
        (NODE_EI(node) != EI_FIELD_MODIFICATION)) {

        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }

    /* Create a class ref that will live beyond */
    /* the end of this call */
    saveGlobalRef(env, clazz, &(filter->clazz));
    FILTER(node, index).modifier = JDWP_REQUEST_MODIFIER(FieldOnly);
    filter->field = field;
    return JVMTI_ERROR_NONE;
}

jvmtiError
eventFilter_setClassOnlyFilter(HandlerNode *node, jint index,
                               jclass clazz)
{
    JNIEnv *env = getEnv();
    ClassFilter *filter = &FILTER(node, index).u.ClassOnly;
    if (index >= FILTER_COUNT(node)) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }
    if (
        (NODE_EI(node) == EI_GC_FINISH) ||
        (NODE_EI(node) == EI_THREAD_START) ||
        (NODE_EI(node) == EI_THREAD_END)) {

        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }

    /* Create a class ref that will live beyond */
    /* the end of this call */
    saveGlobalRef(env, clazz, &(filter->clazz));
    FILTER(node, index).modifier = JDWP_REQUEST_MODIFIER(ClassOnly);
    return JVMTI_ERROR_NONE;
}

jvmtiError
eventFilter_setExceptionOnlyFilter(HandlerNode *node, jint index,
                                   jclass exceptionClass,
                                   jboolean caught,
                                   jboolean uncaught)
{
    JNIEnv *env = getEnv();
    ExceptionFilter *filter = &FILTER(node, index).u.ExceptionOnly;
    if (index >= FILTER_COUNT(node)) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }
    if (NODE_EI(node) != EI_EXCEPTION) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }

    filter->exception = NULL;
    if (exceptionClass != NULL) {
        /* Create a class ref that will live beyond */
        /* the end of this call */
        saveGlobalRef(env, exceptionClass, &(filter->exception));
    }
    FILTER(node, index).modifier =
                       JDWP_REQUEST_MODIFIER(ExceptionOnly);
    filter->caught = caught;
    filter->uncaught = uncaught;
    return JVMTI_ERROR_NONE;
}

jvmtiError
eventFilter_setInstanceOnlyFilter(HandlerNode *node, jint index,
                                  jobject instance)
{
    JNIEnv *env = getEnv();
    InstanceFilter *filter = &FILTER(node, index).u.InstanceOnly;
    if (index >= FILTER_COUNT(node)) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }

    filter->instance = NULL;
    if (instance != NULL) {
        /* Create an object ref that will live beyond
         * the end of this call
         */
        saveGlobalRef(env, instance, &(filter->instance));
    }
    FILTER(node, index).modifier =
                       JDWP_REQUEST_MODIFIER(InstanceOnly);
    return JVMTI_ERROR_NONE;
}

jvmtiError
eventFilter_setClassMatchFilter(HandlerNode *node, jint index,
                                char *classPattern)
{
    MatchFilter *filter = &FILTER(node, index).u.ClassMatch;
    if (index >= FILTER_COUNT(node)) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }
    if (
        (NODE_EI(node) == EI_THREAD_START) ||
        (NODE_EI(node) == EI_THREAD_END)) {

        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }

    FILTER(node, index).modifier =
                       JDWP_REQUEST_MODIFIER(ClassMatch);
    filter->classPattern = classPattern;
    return JVMTI_ERROR_NONE;
}

jvmtiError
eventFilter_setClassExcludeFilter(HandlerNode *node, jint index,
                                  char *classPattern)
{
    MatchFilter *filter = &FILTER(node, index).u.ClassExclude;
    if (index >= FILTER_COUNT(node)) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }
    if (
        (NODE_EI(node) == EI_THREAD_START) ||
        (NODE_EI(node) == EI_THREAD_END)) {

        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }

    FILTER(node, index).modifier =
                       JDWP_REQUEST_MODIFIER(ClassExclude);
    filter->classPattern = classPattern;
    return JVMTI_ERROR_NONE;
}

jvmtiError
eventFilter_setStepFilter(HandlerNode *node, jint index,
                          jthread thread, jint size, jint depth)
{
    jvmtiError error;
    JNIEnv *env = getEnv();
    StepFilter *filter = &FILTER(node, index).u.Step;
    if (index >= FILTER_COUNT(node)) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }
    if (NODE_EI(node) != EI_SINGLE_STEP) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }

    /* Create a thread ref that will live beyond */
    /* the end of this call */
    saveGlobalRef(env, thread, &(filter->thread));
    error = stepControl_beginStep(env, filter->thread, size, depth, node);
    if (error != JVMTI_ERROR_NONE) {
        tossGlobalRef(env, &(filter->thread));
        return error;
    }
    FILTER(node, index).modifier = JDWP_REQUEST_MODIFIER(Step);
    filter->depth = depth;
    filter->size = size;
    return JVMTI_ERROR_NONE;
}


jvmtiError
eventFilter_setSourceNameMatchFilter(HandlerNode *node,
                                    jint index,
                                    char *sourceNamePattern) {
    SourceNameFilter *filter = &FILTER(node, index).u.SourceNameOnly;
    if (index >= FILTER_COUNT(node)) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }
    if (NODE_EI(node) != EI_CLASS_PREPARE) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }

    FILTER(node, index).modifier =
                       JDWP_REQUEST_MODIFIER(SourceNameMatch);
    filter->sourceNamePattern = sourceNamePattern;
    return JVMTI_ERROR_NONE;

}

/***** JVMTI event enabling / disabling *****/

/**
 * Return the Filter that is of the specified type (modifier).
 * Return NULL if not found.
 */
static Filter *
findFilter(HandlerNode *node, jint modifier)
{
    int i;
    Filter *filter;
    for (i = 0, filter = FILTERS_ARRAY(node);
                      i <FILTER_COUNT(node);
                      i++, filter++) {
        if (filter->modifier == modifier) {
            return filter;
        }
    }
    return NULL;
}

/**
 * Determine if the specified breakpoint node is in the
 * same location as the LocationFilter passed in arg.
 *
 * This is a match function called by a
 * eventHandlerRestricted_iterator invokation.
 */
static jboolean
matchBreakpoint(JNIEnv *env, HandlerNode *node, void *arg)
{
    LocationFilter *goal = (LocationFilter *)arg;
    Filter *filter = FILTERS_ARRAY(node);
    int i;

    for (i = 0; i < FILTER_COUNT(node); ++i, ++filter) {
        switch (filter->modifier) {
        case JDWP_REQUEST_MODIFIER(LocationOnly): {
            LocationFilter *trial = &(filter->u.LocationOnly);
            if (trial->method == goal->method &&
                trial->location == goal->location &&
                isSameObject(env, trial->clazz, goal->clazz)) {
                return JNI_TRUE;
            }
        }
        }
    }
    return JNI_FALSE;
}

/**
 * Set a breakpoint if this is the first one at this location.
 */
static jvmtiError
setBreakpoint(HandlerNode *node)
{
    jvmtiError error = JVMTI_ERROR_NONE;
    Filter *filter;

    filter = findFilter(node, JDWP_REQUEST_MODIFIER(LocationOnly));
    if (filter == NULL) {
        /* bp event with no location filter */
        error = AGENT_ERROR_INTERNAL;
    } else {
        LocationFilter *lf = &(filter->u.LocationOnly);

        /* if this is the first handler for this
         * location, set bp at JVMTI level
         */
        if (!eventHandlerRestricted_iterator(
                EI_BREAKPOINT, matchBreakpoint, lf)) {
            LOG_LOC(("SetBreakpoint at location: method=%p,location=%d",
                        lf->method, (int)lf->location));
            error = JVMTI_FUNC_PTR(gdata->jvmti,SetBreakpoint)
                        (gdata->jvmti, lf->method, lf->location);
        }
    }
    return error;
}

/**
 * Clear a breakpoint if this is the last one at this location.
 */
static jvmtiError
clearBreakpoint(HandlerNode *node)
{
    jvmtiError error = JVMTI_ERROR_NONE;
    Filter *filter;

    filter = findFilter(node, JDWP_REQUEST_MODIFIER(LocationOnly));
    if (filter == NULL) {
        /* bp event with no location filter */
        error = AGENT_ERROR_INTERNAL;
    } else {
        LocationFilter *lf = &(filter->u.LocationOnly);

        /* if this is the last handler for this
         * location, clear bp at JVMTI level
         */
        if (!eventHandlerRestricted_iterator(
                EI_BREAKPOINT, matchBreakpoint, lf)) {
            LOG_LOC(("ClearBreakpoint at location: method=%p,location=%d",
                        lf->method, (int)lf->location));
            error = JVMTI_FUNC_PTR(gdata->jvmti,ClearBreakpoint)
                        (gdata->jvmti, lf->method, lf->location);
        }
    }
    return error;
}

/**
 * Return true if a breakpoint is set at the specified location.
 */
jboolean
isBreakpointSet(jclass clazz, jmethodID method, jlocation location)
{
    LocationFilter lf;

    lf.clazz    = clazz;
    lf.method   = method;
    lf.location = location;

    return eventHandlerRestricted_iterator(EI_BREAKPOINT,
                                           matchBreakpoint, &lf);
}

/**
 * Determine if the specified watchpoint node has the
 * same field as the FieldFilter passed in arg.
 *
 * This is a match function called by a
 * eventHandlerRestricted_iterator invokation.
 */
static jboolean
matchWatchpoint(JNIEnv *env, HandlerNode *node, void *arg)
{
    FieldFilter *goal = (FieldFilter *)arg;
    Filter *filter = FILTERS_ARRAY(node);
    int i;

    for (i = 0; i < FILTER_COUNT(node); ++i, ++filter) {
        switch (filter->modifier) {
        case JDWP_REQUEST_MODIFIER(FieldOnly): {
            FieldFilter *trial = &(filter->u.FieldOnly);
            if (trial->field == goal->field &&
                isSameObject(env, trial->clazz, goal->clazz)) {
                return JNI_TRUE;
            }
        }
        }
    }
    return JNI_FALSE;
}

/**
 * Set a watchpoint if this is the first one on this field.
 */
static jvmtiError
setWatchpoint(HandlerNode *node)
{
    jvmtiError error = JVMTI_ERROR_NONE;
    Filter *filter;

    filter = findFilter(node, JDWP_REQUEST_MODIFIER(FieldOnly));
    if (filter == NULL) {
        /* event with no field filter */
        error = AGENT_ERROR_INTERNAL;
    } else {
        FieldFilter *ff = &(filter->u.FieldOnly);

        /* if this is the first handler for this
         * field, set wp at JVMTI level
         */
        if (!eventHandlerRestricted_iterator(
                NODE_EI(node), matchWatchpoint, ff)) {
            error = (NODE_EI(node) == EI_FIELD_ACCESS) ?
                JVMTI_FUNC_PTR(gdata->jvmti,SetFieldAccessWatch)
                        (gdata->jvmti, ff->clazz, ff->field) :
                JVMTI_FUNC_PTR(gdata->jvmti,SetFieldModificationWatch)
                        (gdata->jvmti, ff->clazz, ff->field);
        }
    }
    return error;
}

/**
 * Clear a watchpoint if this is the last one on this field.
 */
static jvmtiError
clearWatchpoint(HandlerNode *node)
{
    jvmtiError error = JVMTI_ERROR_NONE;
    Filter *filter;

    filter = findFilter(node, JDWP_REQUEST_MODIFIER(FieldOnly));
    if (filter == NULL) {
        /* event with no field filter */
        error = AGENT_ERROR_INTERNAL;
    } else {
        FieldFilter *ff = &(filter->u.FieldOnly);

        /* if this is the last handler for this
         * field, clear wp at JVMTI level
         */
        if (!eventHandlerRestricted_iterator(
                NODE_EI(node), matchWatchpoint, ff)) {
            error = (NODE_EI(node) == EI_FIELD_ACCESS) ?
                JVMTI_FUNC_PTR(gdata->jvmti,ClearFieldAccessWatch)
                        (gdata->jvmti, ff->clazz, ff->field) :
                JVMTI_FUNC_PTR(gdata->jvmti,ClearFieldModificationWatch)
                                (gdata->jvmti, ff->clazz, ff->field);
        }
    }
    return error;
}

/**
 * Determine the thread this node is filtered on.
 * NULL if not thread filtered.
 */
static jthread
requestThread(HandlerNode *node)
{
    int i;
    Filter *filter = FILTERS_ARRAY(node);

    for (i = 0; i < FILTER_COUNT(node); ++i, ++filter) {
        switch (filter->modifier) {
            case JDWP_REQUEST_MODIFIER(ThreadOnly):
                return filter->u.ThreadOnly.thread;
        }
    }

    return NULL;
}

/**
 * Determine if the specified node has a
 * thread filter with the thread passed in arg.
 *
 * This is a match function called by a
 * eventHandlerRestricted_iterator invokation.
 */
static jboolean
matchThread(JNIEnv *env, HandlerNode *node, void *arg)
{
    jthread goalThread = (jthread)arg;
    jthread reqThread = requestThread(node);

    /* If the event's thread and the passed thread are the same
     * (or both are NULL), we have a match.
     */
    return isSameObject(env, reqThread, goalThread);
}

/**
 * Do any enabling of events (including setting breakpoints etc)
 * needed to get the events requested by this handler node.
 */
static jvmtiError
enableEvents(HandlerNode *node)
{
    jvmtiError error = JVMTI_ERROR_NONE;

    switch (NODE_EI(node)) {
        /* The stepping code directly enables/disables stepping as
         * necessary
         */
        case EI_SINGLE_STEP:
        /* Internal thread event handlers are always present
         * (hardwired in the event hook), so we don't change the
         * notification mode here.
         */
        case EI_THREAD_START:
        case EI_THREAD_END:
        case EI_VM_INIT:
        case EI_VM_DEATH:
        case EI_CLASS_PREPARE:
        case EI_GC_FINISH:
            return error;

        case EI_FIELD_ACCESS:
        case EI_FIELD_MODIFICATION:
            error = setWatchpoint(node);
            break;

        case EI_BREAKPOINT:
            error = setBreakpoint(node);
            break;

        default:
            break;
    }

    /* Don't globally enable if the above failed */
    if (error == JVMTI_ERROR_NONE) {
        jthread thread = requestThread(node);

        /* If this is the first request of it's kind on this
         * thread (or all threads (thread == NULL)) then enable
         * these events on this thread.
         */
        if (!eventHandlerRestricted_iterator(
                NODE_EI(node), matchThread, thread)) {
            error = threadControl_setEventMode(JVMTI_ENABLE,
                                               NODE_EI(node), thread);
        }
    }
    return error;
}

/**
 * Do any disabling of events (including clearing breakpoints etc)
 * needed to no longer get the events requested by this handler node.
 */
static jvmtiError
disableEvents(HandlerNode *node)
{
    jvmtiError error = JVMTI_ERROR_NONE;
    jvmtiError error2 = JVMTI_ERROR_NONE;
    jthread thread;


    switch (NODE_EI(node)) {
        /* The stepping code directly enables/disables stepping as
         * necessary
         */
        case EI_SINGLE_STEP:
        /* Internal thread event handlers are always present
         * (hardwired in the event hook), so we don't change the
         * notification mode here.
         */
        case EI_THREAD_START:
        case EI_THREAD_END:
        case EI_VM_INIT:
        case EI_VM_DEATH:
        case EI_CLASS_PREPARE:
        case EI_GC_FINISH:
            return error;

        case EI_FIELD_ACCESS:
        case EI_FIELD_MODIFICATION:
            error = clearWatchpoint(node);
            break;

        case EI_BREAKPOINT:
            error = clearBreakpoint(node);
            break;

        default:
            break;
    }

    thread = requestThread(node);

    /* If this is the last request of it's kind on this thread
     * (or all threads (thread == NULL)) then disable these
     * events on this thread.
     *
     * Disable even if the above caused an error
     */
    if (!eventHandlerRestricted_iterator(NODE_EI(node), matchThread, thread)) {
        error2 = threadControl_setEventMode(JVMTI_DISABLE,
                                            NODE_EI(node), thread);
    }
    return error != JVMTI_ERROR_NONE? error : error2;
}


/***** filter (and event) installation and deinstallation *****/

/**
 * Make the set of event filters that correspond with this
 * node active (including enabling the corresponding events).
 */
jvmtiError
eventFilterRestricted_install(HandlerNode *node)
{
    return enableEvents(node);
}

/**
 * Make the set of event filters that correspond with this
 * node inactive (including disabling the corresponding events
 * and freeing resources).
 */
jvmtiError
eventFilterRestricted_deinstall(HandlerNode *node)
{
    jvmtiError error1, error2;

    error1 = disableEvents(node);
    error2 = clearFilters(node);

    return error1 != JVMTI_ERROR_NONE? error1 : error2;
}
