bool V8Value::compare(ScriptValuePtr other)
{
    assert(isValid());
    assert(other->isValid());

    return value->StrictEquals( (dynamic_cast<V8Value*>(other.get()))->value );
}
bool TraceMonkeyValue::compare(ScriptValuePtr other)
{
    assert(isValid());
    assert(other->isValid());

    jsval otherValue = (dynamic_cast<TraceMonkeyValue*>(other.get()))->value;

    if (JSVAL_IS_INT(value))
        return (JSVAL_IS_INT(otherValue) && JSVAL_TO_INT(value) == JSVAL_TO_INT(otherValue));
    else if (JSVAL_IS_NULL(value))
        return (JSVAL_IS_NULL(otherValue));
    else if (JSVAL_IS_VOID(value))
        return (JSVAL_IS_VOID(otherValue));
    else if (JSVAL_IS_BOOLEAN(value))
        return (JSVAL_IS_BOOLEAN(otherValue) && JSVAL_TO_BOOLEAN(value) == JSVAL_TO_BOOLEAN(otherValue));
    else if (JSVAL_IS_DOUBLE(value))
        return (JSVAL_IS_DOUBLE(otherValue) && *(JSVAL_TO_DOUBLE(value)) == *(JSVAL_TO_DOUBLE(otherValue)));
    else if (JSVAL_IS_STRING(value))
    {
        if (!JSVAL_IS_STRING(otherValue))
            return false;
        else
            assert(0 && "TODO: compare TM strings");
    }
    else if (JSVAL_IS_OBJECT(value))
    {
        if (JSVAL_IS_NULL(otherValue)) // NULLs are objects, in TraceMonkey
            return false;
        if (!JSVAL_IS_OBJECT(otherValue))
            return false;
        else
            assert(0 && "TODO: compare TM objects");
    }
    else {
        Logging::log(Logging::INFO, "Can't compare uncertain jsvals\r\n");
    }
    assert(0);
    return false;
}