1/*
2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 */
20
21#pragma once
22
23#include "JSDestructibleObject.h"
24#include "RuntimeType.h"
25#include "StackFrame.h"
26
27namespace JSC {
28
29class ErrorInstance : public JSDestructibleObject {
30public:
31 typedef JSDestructibleObject Base;
32 const static unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
33
34 enum SourceTextWhereErrorOccurred { FoundExactSource, FoundApproximateSource };
35 typedef String (*SourceAppender) (const String& originalMessage, const String& sourceText, RuntimeType, SourceTextWhereErrorOccurred);
36
37 DECLARE_EXPORT_INFO;
38
39 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
40 {
41 return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
42 }
43
44 static ErrorInstance* create(ExecState* exec, VM& vm, Structure* structure, const String& message, SourceAppender appender = nullptr, RuntimeType type = TypeNothing, bool useCurrentFrame = true)
45 {
46 ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(vm.heap)) ErrorInstance(vm, structure);
47 instance->m_sourceAppender = appender;
48 instance->m_runtimeTypeForCause = type;
49 instance->finishCreation(exec, vm, message, useCurrentFrame);
50 return instance;
51 }
52
53 static ErrorInstance* create(ExecState*, Structure*, JSValue message, SourceAppender = nullptr, RuntimeType = TypeNothing, bool useCurrentFrame = true);
54
55 bool hasSourceAppender() const { return !!m_sourceAppender; }
56 SourceAppender sourceAppender() const { return m_sourceAppender; }
57 void setSourceAppender(SourceAppender appender) { m_sourceAppender = appender; }
58 void clearSourceAppender() { m_sourceAppender = nullptr; }
59 void setRuntimeTypeForCause(RuntimeType type) { m_runtimeTypeForCause = type; }
60 RuntimeType runtimeTypeForCause() const { return m_runtimeTypeForCause; }
61 void clearRuntimeTypeForCause() { m_runtimeTypeForCause = TypeNothing; }
62
63 void setStackOverflowError() { m_stackOverflowError = true; }
64 bool isStackOverflowError() const { return m_stackOverflowError; }
65 void setOutOfMemoryError() { m_outOfMemoryError = true; }
66 bool isOutOfMemoryError() const { return m_outOfMemoryError; }
67
68 void setNativeGetterTypeError() { m_nativeGetterTypeError = true; }
69 bool isNativeGetterTypeError() const { return m_nativeGetterTypeError; }
70
71 JS_EXPORT_PRIVATE String sanitizedToString(ExecState*);
72
73 Vector<StackFrame>* stackTrace() { return m_stackTrace.get(); }
74
75 bool materializeErrorInfoIfNeeded(VM&);
76 bool materializeErrorInfoIfNeeded(VM&, PropertyName);
77
78 template<typename CellType, SubspaceAccess mode>
79 static IsoSubspace* subspaceFor(VM& vm)
80 {
81 return vm.errorInstanceSpace<mode>();
82 }
83
84 void finalizeUnconditionally(VM&);
85
86protected:
87 explicit ErrorInstance(VM&, Structure*);
88
89 void finishCreation(ExecState*, VM&, const String&, bool useCurrentFrame = true);
90 static void destroy(JSCell*);
91
92 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
93 static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
94 static void getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
95 static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
96 static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
97 static bool deleteProperty(JSCell*, ExecState*, PropertyName);
98
99 void computeErrorInfo(VM&);
100
101 SourceAppender m_sourceAppender { nullptr };
102 std::unique_ptr<Vector<StackFrame>> m_stackTrace;
103 unsigned m_line;
104 unsigned m_column;
105 String m_sourceURL;
106 String m_stackString;
107 RuntimeType m_runtimeTypeForCause { TypeNothing };
108 bool m_stackOverflowError { false };
109 bool m_outOfMemoryError { false };
110 bool m_errorInfoMaterialized { false };
111 bool m_nativeGetterTypeError { false };
112};
113
114} // namespace JSC
115