We should support CreateThis in the FTL
[WebKit-https.git] / Source / JavaScriptCore / runtime / ErrorConstructor.cpp
1 /*
2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2003-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 #include "config.h"
22 #include "ErrorConstructor.h"
23
24 #include "ErrorPrototype.h"
25 #include "Interpreter.h"
26 #include "JSGlobalObject.h"
27 #include "JSString.h"
28 #include "JSCInlines.h"
29
30 namespace JSC {
31
32 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ErrorConstructor);
33
34 const ClassInfo ErrorConstructor::s_info = { "Function", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ErrorConstructor) };
35
36 ErrorConstructor::ErrorConstructor(VM& vm, Structure* structure)
37     : InternalFunction(vm, structure, Interpreter::callErrorConstructor, Interpreter::constructWithErrorConstructor)
38 {
39 }
40
41 void ErrorConstructor::finishCreation(VM& vm, ErrorPrototype* errorPrototype)
42 {
43     Base::finishCreation(vm, "Error"_s);
44     // ECMA 15.11.3.1 Error.prototype
45     putDirectWithoutTransition(vm, vm.propertyNames->prototype, errorPrototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
46     putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
47
48     unsigned defaultStackTraceLimit = Options::defaultErrorStackTraceLimit();
49     m_stackTraceLimit = defaultStackTraceLimit;
50     putDirectWithoutTransition(vm, vm.propertyNames->stackTraceLimit, jsNumber(defaultStackTraceLimit), static_cast<unsigned>(PropertyAttribute::None));
51 }
52
53 // ECMA 15.9.3
54
55 EncodedJSValue JSC_HOST_CALL Interpreter::constructWithErrorConstructor(ExecState* exec)
56 {
57     VM& vm = exec->vm();
58     auto scope = DECLARE_THROW_SCOPE(vm);
59     JSValue message = exec->argument(0);
60     Structure* errorStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), jsCast<InternalFunction*>(exec->jsCallee())->globalObject(vm)->errorStructure());
61     RETURN_IF_EXCEPTION(scope, encodedJSValue());
62     scope.release();
63     return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, nullptr, TypeNothing, false));
64 }
65
66 EncodedJSValue JSC_HOST_CALL Interpreter::callErrorConstructor(ExecState* exec)
67 {
68     JSValue message = exec->argument(0);
69     Structure* errorStructure = jsCast<InternalFunction*>(exec->jsCallee())->globalObject(exec->vm())->errorStructure();
70     return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, nullptr, TypeNothing, false));
71 }
72
73 bool ErrorConstructor::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
74 {
75     VM& vm = exec->vm();
76     ErrorConstructor* thisObject = jsCast<ErrorConstructor*>(cell);
77
78     if (propertyName == vm.propertyNames->stackTraceLimit) {
79         if (value.isNumber()) {
80             double effectiveLimit = value.asNumber();
81             effectiveLimit = std::max(0., effectiveLimit);
82             effectiveLimit = std::min(effectiveLimit, static_cast<double>(std::numeric_limits<unsigned>::max()));
83             thisObject->m_stackTraceLimit = static_cast<unsigned>(effectiveLimit);
84         } else
85             thisObject->m_stackTraceLimit = { };
86     }
87
88     return Base::put(thisObject, exec, propertyName, value, slot);
89 }
90
91 bool ErrorConstructor::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
92 {
93     VM& vm = exec->vm();
94     ErrorConstructor* thisObject = jsCast<ErrorConstructor*>(cell);
95
96     if (propertyName == vm.propertyNames->stackTraceLimit)
97         thisObject->m_stackTraceLimit = { };
98
99     return Base::deleteProperty(thisObject, exec, propertyName);
100 }
101
102 } // namespace JSC