/*
 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
 *  Copyright (C) 2003-2019 Apple Inc. All rights reserved.
 *  Copyright (C) 2007 Eric Seidel (eric@webkit.org)
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this library; see the file COPYING.LIB.  If not, write to
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301, USA.
 *
 */

#include "config.h"
#include "Error.h"

#include "Interpreter.h"
#include "JSCJSValueInlines.h"
#include "JSGlobalObject.h"
#include "SourceCode.h"
#include "StackFrame.h"

namespace JSC {

JSObject* createError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
{
    ASSERT(!message.isEmpty());
    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(), message, JSValue(), appender, TypeNothing, ErrorType::Error, true);
}

JSObject* createEvalError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
{
    ASSERT(!message.isEmpty());
    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::EvalError), message, JSValue(), appender, TypeNothing, ErrorType::EvalError, true);
}

JSObject* createRangeError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
{
    ASSERT(!message.isEmpty());
    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::RangeError), message, JSValue(), appender, TypeNothing, ErrorType::RangeError, true);
}

JSObject* createReferenceError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
{
    ASSERT(!message.isEmpty());
    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::ReferenceError), message, JSValue(), appender, TypeNothing, ErrorType::ReferenceError, true);
}

JSObject* createSyntaxError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
{
    ASSERT(!message.isEmpty());
    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::SyntaxError), message, JSValue(), appender, TypeNothing, ErrorType::SyntaxError, true);
}

JSObject* createTypeError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender, RuntimeType type)
{
    ASSERT(!message.isEmpty());
    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::TypeError), message, JSValue(), appender, type, ErrorType::TypeError, true);
}

JSObject* createNotEnoughArgumentsError(JSGlobalObject* globalObject, ErrorInstance::SourceAppender appender)
{
    return createTypeError(globalObject, "Not enough arguments"_s, appender, TypeNothing);
}

JSObject* createURIError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
{
    ASSERT(!message.isEmpty());
    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::URIError), message, JSValue(), appender, TypeNothing, ErrorType::URIError, true);
}

JSObject* createError(JSGlobalObject* globalObject, ErrorType errorType, const String& message)
{
    return createError(globalObject, static_cast<ErrorTypeWithExtension>(errorType), message);
}

JSObject* createError(JSGlobalObject* globalObject, ErrorTypeWithExtension errorType, const String& message)
{
    switch (errorType) {
    case ErrorTypeWithExtension::Error:
        return createError(globalObject, message);
    case ErrorTypeWithExtension::EvalError:
        return createEvalError(globalObject, message);
    case ErrorTypeWithExtension::RangeError:
        return createRangeError(globalObject, message);
    case ErrorTypeWithExtension::ReferenceError:
        return createReferenceError(globalObject, message);
    case ErrorTypeWithExtension::SyntaxError:
        return createSyntaxError(globalObject, message);
    case ErrorTypeWithExtension::TypeError:
        return createTypeError(globalObject, message);
    case ErrorTypeWithExtension::URIError:
        return createURIError(globalObject, message);
    case ErrorTypeWithExtension::AggregateError:
        break;
    case ErrorTypeWithExtension::OutOfMemoryError:
        return createOutOfMemoryError(globalObject, message);
    }
    ASSERT_NOT_REACHED();
    return nullptr;
}

static JSObject* createGetterTypeError(JSGlobalObject* globalObject, const String& message)
{
    ASSERT(!message.isEmpty());
    auto* error = ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::TypeError), message, JSValue(), nullptr, TypeNothing, ErrorType::TypeError);
    error->setNativeGetterTypeError();
    return error;
}

class FindFirstCallerFrameWithCodeblockFunctor {
public:
    FindFirstCallerFrameWithCodeblockFunctor(CallFrame* startCallFrame)
        : m_startCallFrame(startCallFrame)
        , m_foundCallFrame(nullptr)
        , m_foundStartCallFrame(false)
        , m_index(0)
    { }

    StackVisitor::Status operator()(StackVisitor& visitor) const
    {
        if (!m_foundStartCallFrame && (visitor->callFrame() == m_startCallFrame))
            m_foundStartCallFrame = true;

        if (m_foundStartCallFrame) {
            if (!visitor->isWasmFrame() && visitor->callFrame()->codeBlock()) {
                m_foundCallFrame = visitor->callFrame();
                return StackVisitor::Done;
            }
            m_index++;
        }

        return StackVisitor::Continue;
    }

    CallFrame* foundCallFrame() const { return m_foundCallFrame; }
    unsigned index() const { return m_index; }

private:
    CallFrame* m_startCallFrame;
    mutable CallFrame* m_foundCallFrame;
    mutable bool m_foundStartCallFrame;
    mutable unsigned m_index;
};

std::unique_ptr<Vector<StackFrame>> getStackTrace(JSGlobalObject*, VM& vm, JSObject* obj, bool useCurrentFrame)
{
    JSGlobalObject* globalObject = obj->globalObject(vm);
    if (!globalObject->stackTraceLimit())
        return nullptr;

    size_t framesToSkip = useCurrentFrame ? 0 : 1;
    std::unique_ptr<Vector<StackFrame>> stackTrace = makeUnique<Vector<StackFrame>>();
    vm.interpreter->getStackTrace(obj, *stackTrace, framesToSkip, globalObject->stackTraceLimit().value());
    return stackTrace;
}

void getBytecodeIndex(VM& vm, CallFrame* startCallFrame, Vector<StackFrame>* stackTrace, CallFrame*& callFrame, BytecodeIndex& bytecodeIndex)
{
    FindFirstCallerFrameWithCodeblockFunctor functor(startCallFrame);
    StackVisitor::visit(vm.topCallFrame, vm, functor);
    callFrame = functor.foundCallFrame();
    unsigned stackIndex = functor.index();
    bytecodeIndex = BytecodeIndex(0);
    if (stackTrace && stackIndex < stackTrace->size() && stackTrace->at(stackIndex).hasBytecodeIndex())
        bytecodeIndex = stackTrace->at(stackIndex).bytecodeIndex();
}

bool getLineColumnAndSource(Vector<StackFrame>* stackTrace, unsigned& line, unsigned& column, String& sourceURL)
{
    line = 0;
    column = 0;
    sourceURL = String();
    
    if (!stackTrace)
        return false;
    
    for (unsigned i = 0 ; i < stackTrace->size(); ++i) {
        StackFrame& frame = stackTrace->at(i);
        if (frame.hasLineAndColumnInfo()) {
            frame.computeLineAndColumn(line, column);
            sourceURL = frame.sourceURL();
            return true;
        }
    }
    
    return false;
}

bool addErrorInfo(VM& vm, Vector<StackFrame>* stackTrace, JSObject* obj)
{
    if (!stackTrace)
        return false;

    if (!stackTrace->isEmpty()) {
        unsigned line;
        unsigned column;
        String sourceURL;
        getLineColumnAndSource(stackTrace, line, column, sourceURL);
        obj->putDirect(vm, vm.propertyNames->line, jsNumber(line));
        obj->putDirect(vm, vm.propertyNames->column, jsNumber(column));
        if (!sourceURL.isEmpty())
            obj->putDirect(vm, vm.propertyNames->sourceURL, jsString(vm, sourceURL));

        obj->putDirect(vm, vm.propertyNames->stack, jsString(vm, Interpreter::stackTraceAsString(vm, *stackTrace)), static_cast<unsigned>(PropertyAttribute::DontEnum));

        return true;
    }

    obj->putDirect(vm, vm.propertyNames->stack, vm.smallStrings.emptyString(), static_cast<unsigned>(PropertyAttribute::DontEnum));
    return false;
}

void addErrorInfo(JSGlobalObject* globalObject, JSObject* obj, bool useCurrentFrame)
{
    VM& vm = globalObject->vm();
    std::unique_ptr<Vector<StackFrame>> stackTrace = getStackTrace(globalObject, vm, obj, useCurrentFrame);
    addErrorInfo(vm, stackTrace.get(), obj);
}

JSObject* addErrorInfo(VM& vm, JSObject* error, int line, const SourceCode& source)
{
    const String& sourceURL = source.provider()->sourceURL();
    
    // The putDirect() calls below should really be put() so that they trigger materialization of
    // the line/sourceURL properties. Otherwise, what we set here will just be overwritten later.
    // But calling put() would be bad because we'd rather not do effectful things here. Luckily, we
    // know that this will get called on some kind of error - so we can just directly ask the
    // ErrorInstance to materialize whatever it needs to. There's a chance that we get passed some
    // other kind of object, which also has materializable properties. But this code is heuristic-ey
    // enough that if we're wrong in such corner cases, it's not the end of the world.
    if (ErrorInstance* errorInstance = jsDynamicCast<ErrorInstance*>(vm, error))
        errorInstance->materializeErrorInfoIfNeeded(vm);
    
    // FIXME: This does not modify the column property, which confusingly continues to reflect
    // the column at which the exception was thrown.
    // https://bugs.webkit.org/show_bug.cgi?id=176673
    if (line != -1)
        error->putDirect(vm, vm.propertyNames->line, jsNumber(line));
    if (!sourceURL.isNull())
        error->putDirect(vm, vm.propertyNames->sourceURL, jsString(vm, sourceURL));
    return error;
}

String makeDOMAttributeGetterTypeErrorMessage(const char* interfaceName, const String& attributeName)
{
    return makeString("The ", interfaceName, '.', attributeName, " getter can only be used on instances of ", interfaceName);
}

String makeDOMAttributeSetterTypeErrorMessage(const char* interfaceName, const String& attributeName)
{
    return makeString("The ", interfaceName, '.', attributeName, " setter can only be used on instances of ", interfaceName);
}

Exception* throwConstructorCannotBeCalledAsFunctionTypeError(JSGlobalObject* globalObject, ThrowScope& scope, const char* constructorName)
{
    return throwTypeError(globalObject, scope, makeString("calling ", constructorName, " constructor without new is invalid"));
}

Exception* throwTypeError(JSGlobalObject* globalObject, ThrowScope& scope)
{
    return throwException(globalObject, scope, createTypeError(globalObject));
}

Exception* throwTypeError(JSGlobalObject* globalObject, ThrowScope& scope, ASCIILiteral errorMessage)
{
    return throwTypeError(globalObject, scope, String(errorMessage));
}

Exception* throwTypeError(JSGlobalObject* globalObject, ThrowScope& scope, const String& message)
{
    return throwException(globalObject, scope, createTypeError(globalObject, message));
}

Exception* throwSyntaxError(JSGlobalObject* globalObject, ThrowScope& scope)
{
    return throwException(globalObject, scope, createSyntaxError(globalObject));
}

Exception* throwSyntaxError(JSGlobalObject* globalObject, ThrowScope& scope, const String& message)
{
    return throwException(globalObject, scope, createSyntaxError(globalObject, message));
}

JSValue throwDOMAttributeGetterTypeError(JSGlobalObject* globalObject, ThrowScope& scope, const ClassInfo* classInfo, PropertyName propertyName)
{
    return throwException(globalObject, scope, createGetterTypeError(globalObject, makeDOMAttributeGetterTypeErrorMessage(classInfo->className, String(propertyName.uid()))));
}

JSValue throwDOMAttributeSetterTypeError(JSGlobalObject* globalObject, ThrowScope& scope, const ClassInfo* classInfo, PropertyName propertyName)
{
    return throwException(globalObject, scope, createTypeError(globalObject, makeDOMAttributeSetterTypeErrorMessage(classInfo->className, String(propertyName.uid()))));
}

JSObject* createError(JSGlobalObject* globalObject, const String& message)
{
    return createError(globalObject, message, nullptr);
}

JSObject* createEvalError(JSGlobalObject* globalObject, const String& message)
{
    return createEvalError(globalObject, message, nullptr);
}

JSObject* createRangeError(JSGlobalObject* globalObject, const String& message)
{
    return createRangeError(globalObject, message, nullptr);
}

JSObject* createReferenceError(JSGlobalObject* globalObject, const String& message)
{
    return createReferenceError(globalObject, message, nullptr);
}

JSObject* createSyntaxError(JSGlobalObject* globalObject, const String& message)
{
    return createSyntaxError(globalObject, message, nullptr);
}

JSObject* createSyntaxError(JSGlobalObject* globalObject)
{
    return createSyntaxError(globalObject, "Syntax error"_s, nullptr);
}

JSObject* createTypeError(JSGlobalObject* globalObject)
{
    return createTypeError(globalObject, "Type error"_s);
}

JSObject* createTypeError(JSGlobalObject* globalObject, const String& message)
{
    return createTypeError(globalObject, message, nullptr, TypeNothing);
}

JSObject* createNotEnoughArgumentsError(JSGlobalObject* globalObject)
{
    return createNotEnoughArgumentsError(globalObject, nullptr);
}

JSObject* createURIError(JSGlobalObject* globalObject, const String& message)
{
    return createURIError(globalObject, message, nullptr);
}

JSObject* createOutOfMemoryError(JSGlobalObject* globalObject)
{
    auto* error = createRangeError(globalObject, "Out of memory"_s, nullptr);
    jsCast<ErrorInstance*>(error)->setOutOfMemoryError();
    return error;
}

JSObject* createOutOfMemoryError(JSGlobalObject* globalObject, const String& message)
{
    if (message.isEmpty())
        return createOutOfMemoryError(globalObject);
    auto* error = createRangeError(globalObject, makeString("Out of memory: ", message), nullptr);
    jsCast<ErrorInstance*>(error)->setOutOfMemoryError();
    return error;
}

} // namespace JSC
