1 | /* |
2 | * Copyright (C) 1999-2000 Harri Porten ([email protected]) |
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 | static EncodedJSValue JSC_HOST_CALL callErrorConstructor(ExecState*); |
37 | static EncodedJSValue JSC_HOST_CALL constructErrorConstructor(ExecState*); |
38 | |
39 | ErrorConstructor::ErrorConstructor(VM& vm, Structure* structure) |
40 | : InternalFunction(vm, structure, callErrorConstructor, constructErrorConstructor) |
41 | { |
42 | } |
43 | |
44 | void ErrorConstructor::finishCreation(VM& vm, ErrorPrototype* errorPrototype) |
45 | { |
46 | Base::finishCreation(vm, vm.propertyNames->Error.string(), NameVisibility::Visible, NameAdditionMode::WithoutStructureTransition); |
47 | // ECMA 15.11.3.1 Error.prototype |
48 | putDirectWithoutTransition(vm, vm.propertyNames->prototype, errorPrototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); |
49 | putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); |
50 | putDirectWithoutTransition(vm, vm.propertyNames->stackTraceLimit, jsNumber(globalObject(vm)->stackTraceLimit().valueOr(Options::defaultErrorStackTraceLimit())), static_cast<unsigned>(PropertyAttribute::None)); |
51 | } |
52 | |
53 | // ECMA 15.9.3 |
54 | |
55 | EncodedJSValue JSC_HOST_CALL constructErrorConstructor(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 | RELEASE_AND_RETURN(scope, JSValue::encode(ErrorInstance::create(exec, errorStructure, message, nullptr, TypeNothing, false))); |
63 | } |
64 | |
65 | EncodedJSValue JSC_HOST_CALL callErrorConstructor(ExecState* exec) |
66 | { |
67 | JSValue message = exec->argument(0); |
68 | Structure* errorStructure = jsCast<InternalFunction*>(exec->jsCallee())->globalObject(exec->vm())->errorStructure(); |
69 | return JSValue::encode(ErrorInstance::create(exec, errorStructure, message, nullptr, TypeNothing, false)); |
70 | } |
71 | |
72 | bool ErrorConstructor::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) |
73 | { |
74 | VM& vm = exec->vm(); |
75 | ErrorConstructor* thisObject = jsCast<ErrorConstructor*>(cell); |
76 | |
77 | if (propertyName == vm.propertyNames->stackTraceLimit) { |
78 | if (value.isNumber()) { |
79 | double effectiveLimit = value.asNumber(); |
80 | effectiveLimit = std::max(0., effectiveLimit); |
81 | effectiveLimit = std::min(effectiveLimit, static_cast<double>(std::numeric_limits<unsigned>::max())); |
82 | thisObject->globalObject(vm)->setStackTraceLimit(static_cast<unsigned>(effectiveLimit)); |
83 | } else |
84 | thisObject->globalObject(vm)->setStackTraceLimit(WTF::nullopt); |
85 | } |
86 | |
87 | return Base::put(thisObject, exec, propertyName, value, slot); |
88 | } |
89 | |
90 | bool ErrorConstructor::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) |
91 | { |
92 | VM& vm = exec->vm(); |
93 | ErrorConstructor* thisObject = jsCast<ErrorConstructor*>(cell); |
94 | |
95 | if (propertyName == vm.propertyNames->stackTraceLimit) |
96 | thisObject->globalObject(vm)->setStackTraceLimit(WTF::nullopt); |
97 | |
98 | return Base::deleteProperty(thisObject, exec, propertyName); |
99 | } |
100 | |
101 | } // namespace JSC |
102 | |