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 JS_EXPORT_PRIVATE String sanitizedToString(ExecState*);
69
70 Vector<StackFrame>* stackTrace() { return m_stackTrace.get(); }
71
72 bool materializeErrorInfoIfNeeded(VM&);
73 bool materializeErrorInfoIfNeeded(VM&, PropertyName);
74
75 template<typename CellType, SubspaceAccess mode>
76 static IsoSubspace* subspaceFor(VM& vm)
77 {
78 return vm.errorInstanceSpace<mode>();
79 }
80
81 void finalizeUnconditionally(VM&);
82
83protected:
84 explicit ErrorInstance(VM&, Structure*);
85
86 void finishCreation(ExecState*, VM&, const String&, bool useCurrentFrame = true);
87 static void destroy(JSCell*);
88
89 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
90 static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
91 static void getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
92 static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
93 static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
94 static bool deleteProperty(JSCell*, ExecState*, PropertyName);
95
96 void computeErrorInfo(VM&);
97
98 SourceAppender m_sourceAppender { nullptr };
99 std::unique_ptr<Vector<StackFrame>> m_stackTrace;
100 unsigned m_line;
101 unsigned m_column;
102 String m_sourceURL;
103 String m_stackString;
104 RuntimeType m_runtimeTypeForCause { TypeNothing };
105 bool m_stackOverflowError { false };
106 bool m_outOfMemoryError { false };
107 bool m_errorInfoMaterialized { false };
108};
109
110} // namespace JSC
111