15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Google Inc. All rights reserved.
302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1.  Redistributions of source code must retain the above copyright
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer.
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2.  Redistributions in binary form must reproduce the above copyright
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer in the
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     documentation and/or other materials provided with the distribution.
1202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
26197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/V8ThrowException.h"
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
28197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/V8Binding.h"
29f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/core/v8/V8DOMException.h"
30591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/dom/DOMException.h"
31591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/dom/ExceptionCode.h"
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
33c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
355267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)static void domExceptionStackGetter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(info.Data()->IsObject());
38a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    v8SetReturnValue(info, info.Data()->ToObject()->Get(v8AtomicString(info.GetIsolate(), "stack")));
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)static void domExceptionStackSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(info.Data()->IsObject());
44a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    info.Data()->ToObject()->Set(v8AtomicString(info.GetIsolate(), "stack"), value);
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)v8::Handle<v8::Value> V8ThrowException::createDOMException(int ec, const String& sanitizedMessage, const String& unsanitizedMessage, const v8::Handle<v8::Object>& creationContext, v8::Isolate* isolate)
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (ec <= 0 || v8::V8::IsExecutionTerminating())
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return v8Undefined();
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
52e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT(ec == SecurityError || unsanitizedMessage.isEmpty());
53e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
54c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (ec == V8GeneralError)
55c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return V8ThrowException::createGeneralError(sanitizedMessage, isolate);
56c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (ec == V8TypeError)
57e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        return V8ThrowException::createTypeError(sanitizedMessage, isolate);
58c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (ec == V8RangeError)
59c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return V8ThrowException::createRangeError(sanitizedMessage, isolate);
60c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (ec == V8SyntaxError)
61c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return V8ThrowException::createSyntaxError(sanitizedMessage, isolate);
62c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (ec == V8ReferenceError)
63c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return V8ThrowException::createReferenceError(sanitizedMessage, isolate);
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
65f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    RefPtrWillBeRawPtr<DOMException> domException = DOMException::create(ec, sanitizedMessage, unsanitizedMessage);
6651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    v8::Handle<v8::Value> exception = toV8(domException, creationContext, isolate);
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (exception.IsEmpty())
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return v8Undefined();
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Attach an Error object to the DOMException. This is then lazily used to get the stack value.
72a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    v8::Handle<v8::Value> error = v8::Exception::Error(v8String(isolate, domException->message()));
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!error.IsEmpty());
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(exception->IsObject());
75a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    exception->ToObject()->SetAccessor(v8AtomicString(isolate, "stack"), domExceptionStackGetter, domExceptionStackSetter, error);
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
77e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    return exception;
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)v8::Handle<v8::Value> V8ThrowException::throwDOMException(int ec, const String& sanitizedMessage, const String& unsanitizedMessage, const v8::Handle<v8::Object>& creationContext, v8::Isolate* isolate)
81e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{
82e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    ASSERT(ec == SecurityError || unsanitizedMessage.isEmpty());
8351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    v8::Handle<v8::Value> exception = createDOMException(ec, sanitizedMessage, unsanitizedMessage, creationContext, isolate);
84e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (exception.IsEmpty())
85e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        return v8Undefined();
86e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
87c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return V8ThrowException::throwException(exception, isolate);
88e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}
89e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
90c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)v8::Handle<v8::Value> V8ThrowException::createGeneralError(const String& message, v8::Isolate* isolate)
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
92c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return v8::Exception::Error(v8String(isolate, message.isNull() ? "Error" : message));
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
95c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)v8::Handle<v8::Value> V8ThrowException::throwGeneralError(const String& message, v8::Isolate* isolate)
96e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{
97c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    v8::Handle<v8::Value> exception = V8ThrowException::createGeneralError(message, isolate);
98c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return V8ThrowException::throwException(exception, isolate);
99e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}
100e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
1017757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochv8::Handle<v8::Value> V8ThrowException::createTypeError(const String& message, v8::Isolate* isolate)
102e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{
103a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    return v8::Exception::TypeError(v8String(isolate, message.isNull() ? "Type error" : message));
104e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}
105e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
1067757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochv8::Handle<v8::Value> V8ThrowException::throwTypeError(const String& message, v8::Isolate* isolate)
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
108e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    v8::Handle<v8::Value> exception = V8ThrowException::createTypeError(message, isolate);
109c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return V8ThrowException::throwException(exception, isolate);
110c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
111c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
112c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)v8::Handle<v8::Value> V8ThrowException::createRangeError(const String& message, v8::Isolate* isolate)
113c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
114c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return v8::Exception::RangeError(v8String(isolate, message.isNull() ? "Range error" : message));
115c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
116c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
117c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)v8::Handle<v8::Value> V8ThrowException::throwRangeError(const String& message, v8::Isolate* isolate)
118c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
119c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    v8::Handle<v8::Value> exception = V8ThrowException::createRangeError(message, isolate);
120c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return V8ThrowException::throwException(exception, isolate);
121c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
122c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
123c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)v8::Handle<v8::Value> V8ThrowException::createSyntaxError(const String& message, v8::Isolate* isolate)
124c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
125c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return v8::Exception::SyntaxError(v8String(isolate, message.isNull() ? "Syntax error" : message));
126c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
127c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
128c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)v8::Handle<v8::Value> V8ThrowException::throwSyntaxError(const String& message, v8::Isolate* isolate)
129c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
130c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    v8::Handle<v8::Value> exception = V8ThrowException::createSyntaxError(message, isolate);
131c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return V8ThrowException::throwException(exception, isolate);
132c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
133c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
134c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)v8::Handle<v8::Value> V8ThrowException::createReferenceError(const String& message, v8::Isolate* isolate)
135c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
136c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return v8::Exception::ReferenceError(v8String(isolate, message.isNull() ? "Reference error" : message));
137c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
138c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
139c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)v8::Handle<v8::Value> V8ThrowException::throwReferenceError(const String& message, v8::Isolate* isolate)
140c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
141c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    v8::Handle<v8::Value> exception = V8ThrowException::createReferenceError(message, isolate);
142c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return V8ThrowException::throwException(exception, isolate);
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
145c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)v8::Handle<v8::Value> V8ThrowException::throwException(v8::Handle<v8::Value> exception, v8::Isolate* isolate)
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!v8::V8::IsExecutionTerminating())
148a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        isolate->ThrowException(exception);
1499bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    return v8::Undefined(isolate);
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
152c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
153