2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Eric Seidel (eric@webkit.org)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
27 #include "ConstructData.h"
28 #include "ErrorConstructor.h"
29 #include "ExceptionHelpers.h"
30 #include "FunctionPrototype.h"
32 #include "JSFunction.h"
33 #include "JSGlobalObject.h"
36 #include "NativeErrorConstructor.h"
37 #include "JSCInlines.h"
38 #include "SourceCode.h"
40 #include <wtf/text/StringBuilder.h>
44 static const char* linePropertyName
= "line";
45 static const char* sourceURLPropertyName
= "sourceURL";
47 JSObject
* createError(ExecState
* exec
, const String
& message
, ErrorInstance::SourceAppender appender
)
49 ASSERT(!message
.isEmpty());
50 JSGlobalObject
* globalObject
= exec
->lexicalGlobalObject();
51 return ErrorInstance::create(exec
, globalObject
->vm(), globalObject
->errorStructure(), message
, appender
, TypeNothing
, true);
54 JSObject
* createEvalError(ExecState
* exec
, const String
& message
, ErrorInstance::SourceAppender appender
)
56 ASSERT(!message
.isEmpty());
57 JSGlobalObject
* globalObject
= exec
->lexicalGlobalObject();
58 return ErrorInstance::create(exec
, globalObject
->vm(), globalObject
->evalErrorConstructor()->errorStructure(), message
, appender
, TypeNothing
, true);
61 JSObject
* createRangeError(ExecState
* exec
, const String
& message
, ErrorInstance::SourceAppender appender
)
63 ASSERT(!message
.isEmpty());
64 JSGlobalObject
* globalObject
= exec
->lexicalGlobalObject();
65 return ErrorInstance::create(exec
, globalObject
->vm(), globalObject
->rangeErrorConstructor()->errorStructure(), message
, appender
, TypeNothing
, true);
68 JSObject
* createReferenceError(ExecState
* exec
, const String
& message
, ErrorInstance::SourceAppender appender
)
70 ASSERT(!message
.isEmpty());
71 JSGlobalObject
* globalObject
= exec
->lexicalGlobalObject();
72 return ErrorInstance::create(exec
, globalObject
->vm(), globalObject
->referenceErrorConstructor()->errorStructure(), message
, appender
, TypeNothing
, true);
75 JSObject
* createSyntaxError(ExecState
* exec
, const String
& message
, ErrorInstance::SourceAppender appender
)
77 ASSERT(!message
.isEmpty());
78 JSGlobalObject
* globalObject
= exec
->lexicalGlobalObject();
79 return ErrorInstance::create(exec
, globalObject
->vm(), globalObject
->syntaxErrorConstructor()->errorStructure(), message
, appender
, TypeNothing
, true);
82 JSObject
* createTypeError(ExecState
* exec
, const String
& message
, ErrorInstance::SourceAppender appender
, RuntimeType type
)
84 ASSERT(!message
.isEmpty());
85 JSGlobalObject
* globalObject
= exec
->lexicalGlobalObject();
86 return ErrorInstance::create(exec
, globalObject
->vm(), globalObject
->typeErrorConstructor()->errorStructure(), message
, appender
, type
, true);
89 JSObject
* createNotEnoughArgumentsError(ExecState
* exec
, ErrorInstance::SourceAppender appender
)
91 return createTypeError(exec
, ASCIILiteral("Not enough arguments"), appender
, TypeNothing
);
94 JSObject
* createURIError(ExecState
* exec
, const String
& message
, ErrorInstance::SourceAppender appender
)
96 ASSERT(!message
.isEmpty());
97 JSGlobalObject
* globalObject
= exec
->lexicalGlobalObject();
98 return ErrorInstance::create(exec
, globalObject
->vm(), globalObject
->URIErrorConstructor()->errorStructure(), message
, appender
, TypeNothing
, true);
101 JSObject
* createOutOfMemoryError(ExecState
* exec
, ErrorInstance::SourceAppender appender
)
103 return createError(exec
, ASCIILiteral("Out of memory"), appender
);
107 class FindFirstCallerFrameWithCodeblockFunctor
{
109 FindFirstCallerFrameWithCodeblockFunctor(CallFrame
* startCallFrame
)
110 : m_startCallFrame(startCallFrame
)
111 , m_foundCallFrame(nullptr)
112 , m_foundStartCallFrame(false)
116 StackVisitor::Status
operator()(StackVisitor
& visitor
)
118 if (!m_foundStartCallFrame
&& (visitor
->callFrame() == m_startCallFrame
))
119 m_foundStartCallFrame
= true;
121 if (m_foundStartCallFrame
) {
122 if (visitor
->callFrame()->codeBlock()) {
123 m_foundCallFrame
= visitor
->callFrame();
124 return StackVisitor::Done
;
129 return StackVisitor::Continue
;
132 CallFrame
* foundCallFrame() const { return m_foundCallFrame
; }
133 unsigned index() const { return m_index
; }
136 CallFrame
* m_startCallFrame
;
137 CallFrame
* m_foundCallFrame
;
138 bool m_foundStartCallFrame
;
142 bool addErrorInfoAndGetBytecodeOffset(ExecState
* exec
, VM
& vm
, JSObject
* obj
, bool useCurrentFrame
, CallFrame
*& callFrame
, unsigned &bytecodeOffset
)
144 Vector
<StackFrame
> stackTrace
= Vector
<StackFrame
>();
146 if (exec
&& stackTrace
.isEmpty())
147 vm
.interpreter
->getStackTrace(stackTrace
);
149 if (!stackTrace
.isEmpty()) {
151 ASSERT(exec
== vm
.topCallFrame
|| exec
== exec
->lexicalGlobalObject()->globalExec() || exec
== exec
->vmEntryGlobalObject()->globalExec());
153 StackFrame
* stackFrame
;
154 for (unsigned i
= 0 ; i
< stackTrace
.size(); ++i
) {
155 stackFrame
= &stackTrace
.at(i
);
156 if (stackFrame
->bytecodeOffset
)
160 if (bytecodeOffset
) {
161 FindFirstCallerFrameWithCodeblockFunctor
functor(exec
);
162 vm
.topCallFrame
->iterate(functor
);
163 callFrame
= functor
.foundCallFrame();
164 unsigned stackIndex
= functor
.index();
165 bytecodeOffset
= stackTrace
.at(stackIndex
).bytecodeOffset
;
170 stackFrame
->computeLineAndColumn(line
, column
);
171 obj
->putDirect(vm
, vm
.propertyNames
->line
, jsNumber(line
), ReadOnly
| DontDelete
);
172 obj
->putDirect(vm
, vm
.propertyNames
->column
, jsNumber(column
), ReadOnly
| DontDelete
);
174 if (!stackFrame
->sourceURL
.isEmpty())
175 obj
->putDirect(vm
, vm
.propertyNames
->sourceURL
, jsString(&vm
, stackFrame
->sourceURL
), ReadOnly
| DontDelete
);
177 if (!useCurrentFrame
)
178 stackTrace
.remove(0);
179 obj
->putDirect(vm
, vm
.propertyNames
->stack
, vm
.interpreter
->stackTraceAsString(vm
.topCallFrame
, stackTrace
), DontEnum
);
186 void addErrorInfo(ExecState
* exec
, JSObject
* obj
, bool useCurrentFrame
)
188 CallFrame
* callFrame
= nullptr;
189 unsigned bytecodeOffset
= 0;
190 addErrorInfoAndGetBytecodeOffset(exec
, exec
->vm(), obj
, useCurrentFrame
, callFrame
, bytecodeOffset
);
193 JSObject
* addErrorInfo(CallFrame
* callFrame
, JSObject
* error
, int line
, const SourceCode
& source
)
195 VM
* vm
= &callFrame
->vm();
196 const String
& sourceURL
= source
.provider()->url();
199 error
->putDirect(*vm
, Identifier::fromString(vm
, linePropertyName
), jsNumber(line
), ReadOnly
| DontDelete
);
200 if (!sourceURL
.isNull())
201 error
->putDirect(*vm
, Identifier::fromString(vm
, sourceURLPropertyName
), jsString(vm
, sourceURL
), ReadOnly
| DontDelete
);
206 bool hasErrorInfo(ExecState
* exec
, JSObject
* error
)
208 return error
->hasProperty(exec
, Identifier::fromString(exec
, linePropertyName
))
209 || error
->hasProperty(exec
, Identifier::fromString(exec
, sourceURLPropertyName
));
212 JSObject
* throwTypeError(ExecState
* exec
)
214 return exec
->vm().throwException(exec
, createTypeError(exec
));
217 JSObject
* throwSyntaxError(ExecState
* exec
)
219 return exec
->vm().throwException(exec
, createSyntaxError(exec
, ASCIILiteral("Syntax error")));
223 JSObject
* createError(ExecState
* exec
, const String
& message
)
225 return createError(exec
, message
, nullptr);
228 JSObject
* createEvalError(ExecState
* exec
, const String
& message
)
230 return createEvalError(exec
, message
, nullptr);
233 JSObject
* createRangeError(ExecState
* exec
, const String
& message
)
235 return createRangeError(exec
, message
, nullptr);
238 JSObject
* createReferenceError(ExecState
* exec
, const String
& message
)
240 return createReferenceError(exec
, message
, nullptr);
243 JSObject
* createSyntaxError(ExecState
* exec
, const String
& message
)
245 return createSyntaxError(exec
, message
, nullptr);
248 JSObject
* createTypeError(ExecState
* exec
)
250 return createTypeError(exec
, ASCIILiteral("Type error"));
253 JSObject
* createTypeError(ExecState
* exec
, const String
& message
)
255 return createTypeError(exec
, message
, nullptr, TypeNothing
);
258 JSObject
* createNotEnoughArgumentsError(ExecState
* exec
)
260 return createNotEnoughArgumentsError(exec
, nullptr);
263 JSObject
* createURIError(ExecState
* exec
, const String
& message
)
265 return createURIError(exec
, message
, nullptr);
268 JSObject
* createOutOfMemoryError(ExecState
* exec
)
270 return createOutOfMemoryError(exec
, nullptr);
274 const ClassInfo
StrictModeTypeErrorFunction::s_info
= { "Function", &Base::s_info
, 0, CREATE_METHOD_TABLE(StrictModeTypeErrorFunction
) };
276 void StrictModeTypeErrorFunction::destroy(JSCell
* cell
)
278 static_cast<StrictModeTypeErrorFunction
*>(cell
)->StrictModeTypeErrorFunction::~StrictModeTypeErrorFunction();