1/* 2 * Copyright (C) 2008 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#ifndef LabelScope_h 30#define LabelScope_h 31 32#include <wtf/PassRefPtr.h> 33#include "Label.h" 34 35namespace JSC { 36 37 class Identifier; 38 39 class LabelScope { 40 public: 41 enum Type { Loop, Switch, NamedLabel }; 42 43 LabelScope(Type type, const Identifier* name, int scopeDepth, PassRefPtr<Label> breakTarget, PassRefPtr<Label> continueTarget) 44 : m_refCount(0) 45 , m_type(type) 46 , m_name(name) 47 , m_scopeDepth(scopeDepth) 48 , m_breakTarget(breakTarget) 49 , m_continueTarget(continueTarget) 50 { 51 } 52 int refCount() const { return m_refCount; } 53 54 Label* breakTarget() const { return m_breakTarget.get(); } 55 Label* continueTarget() const { return m_continueTarget.get(); } 56 57 Type type() const { return m_type; } 58 const Identifier* name() const { return m_name; } 59 int scopeDepth() const { return m_scopeDepth; } 60 61 private: 62 friend class LabelScopePtr; 63 64 void ref() { ++m_refCount; } 65 void deref() 66 { 67 --m_refCount; 68 ASSERT(m_refCount >= 0); 69 } 70 71 int m_refCount; 72 Type m_type; 73 const Identifier* m_name; 74 int m_scopeDepth; 75 RefPtr<Label> m_breakTarget; 76 RefPtr<Label> m_continueTarget; 77 }; 78 79 typedef Vector<LabelScope, 8> LabelScopeStore; 80 81 class LabelScopePtr { 82 public: 83 LabelScopePtr() 84 : m_owner(0) 85 , m_index(0) 86 { 87 } 88 LabelScopePtr(LabelScopeStore* owner, size_t index) 89 : m_owner(owner) 90 , m_index(index) 91 { 92 m_owner->at(index).ref(); 93 } 94 95 LabelScopePtr(const LabelScopePtr& other) 96 : m_owner(other.m_owner) 97 , m_index(other.m_index) 98 { 99 if (m_owner) 100 m_owner->at(m_index).ref(); 101 } 102 103 const LabelScopePtr& operator=(const LabelScopePtr& other) 104 { 105 if (other.m_owner) 106 other.m_owner->at(other.m_index).ref(); 107 if (m_owner) 108 m_owner->at(m_index).deref(); 109 m_owner = other.m_owner; 110 m_index = other.m_index; 111 return *this; 112 } 113 114 ~LabelScopePtr() 115 { 116 if (m_owner) 117 m_owner->at(m_index).deref(); 118 } 119 120 LabelScope& operator*() { ASSERT(m_owner); return m_owner->at(m_index); } 121 LabelScope* operator->() { ASSERT(m_owner); return &m_owner->at(m_index); } 122 const LabelScope& operator*() const { ASSERT(m_owner); return m_owner->at(m_index); } 123 const LabelScope* operator->() const { ASSERT(m_owner); return &m_owner->at(m_index); } 124 125 private: 126 LabelScopeStore* m_owner; 127 size_t m_index; 128 }; 129 130} // namespace JSC 131 132#endif // LabelScope_h 133