• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // Copyright 2012 the V8 project authors. All rights reserved.
2  // Redistribution and use in source and binary forms, with or without
3  // modification, are permitted provided that the following conditions are
4  // met:
5  //
6  //     * Redistributions of source code must retain the above copyright
7  //       notice, this list of conditions and the following disclaimer.
8  //     * Redistributions in binary form must reproduce the above
9  //       copyright notice, this list of conditions and the following
10  //       disclaimer in the documentation and/or other materials provided
11  //       with the distribution.
12  //     * Neither the name of Google Inc. nor the names of its
13  //       contributors may be used to endorse or promote products derived
14  //       from this software without specific prior written permission.
15  //
16  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  
28  #ifndef V8_INTERFACE_H_
29  #define V8_INTERFACE_H_
30  
31  #include "zone-inl.h"  // For operator new.
32  
33  namespace v8 {
34  namespace internal {
35  
36  
37  // This class implements the following abstract grammar of interfaces
38  // (i.e. module types):
39  //   interface ::= UNDETERMINED | VALUE | MODULE(exports)
40  //   exports ::= {name : interface, ...}
41  // A frozen module type is one that is fully determined. Unification does not
42  // allow adding additional exports to frozen interfaces.
43  // Otherwise, unifying modules merges their exports.
44  // Undetermined types are unification variables that can be unified freely.
45  
46  class Interface : public ZoneObject {
47   public:
48    // ---------------------------------------------------------------------------
49    // Factory methods.
50  
NewValue()51    static Interface* NewValue() {
52      static Interface value_interface(VALUE + FROZEN);  // Cached.
53      return &value_interface;
54    }
55  
NewUnknown()56    static Interface* NewUnknown() {
57      return new Interface(NONE);
58    }
59  
NewModule()60    static Interface* NewModule() {
61      return new Interface(MODULE);
62    }
63  
64    // ---------------------------------------------------------------------------
65    // Mutators.
66  
67    // Add a name to the list of exports. If it already exists, unify with
68    // interface, otherwise insert unless this is closed.
Add(Handle<String> name,Interface * interface,bool * ok)69    void Add(Handle<String> name, Interface* interface, bool* ok) {
70      DoAdd(name.location(), name->Hash(), interface, ok);
71    }
72  
73    // Unify with another interface. If successful, both interface objects will
74    // represent the same type, and changes to one are reflected in the other.
75    void Unify(Interface* that, bool* ok);
76  
77    // Determine this interface to be a value interface.
MakeValue(bool * ok)78    void MakeValue(bool* ok) {
79      *ok = !IsModule();
80      if (*ok) Chase()->flags_ |= VALUE;
81    }
82  
83    // Determine this interface to be a module interface.
MakeModule(bool * ok)84    void MakeModule(bool* ok) {
85      *ok = !IsValue();
86      if (*ok) Chase()->flags_ |= MODULE;
87    }
88  
89    // Do not allow any further refinements, directly or through unification.
Freeze(bool * ok)90    void Freeze(bool* ok) {
91      *ok = IsValue() || IsModule();
92      if (*ok) Chase()->flags_ |= FROZEN;
93    }
94  
95    // ---------------------------------------------------------------------------
96    // Accessors.
97  
98    // Look up an exported name. Returns NULL if not (yet) defined.
99    Interface* Lookup(Handle<String> name);
100  
101    // Check whether this is still a fully undetermined type.
IsUnknown()102    bool IsUnknown() { return Chase()->flags_ == NONE; }
103  
104    // Check whether this is a value type.
IsValue()105    bool IsValue() { return Chase()->flags_ & VALUE; }
106  
107    // Check whether this is a module type.
IsModule()108    bool IsModule() { return Chase()->flags_ & MODULE; }
109  
110    // Check whether this is closed (i.e. fully determined).
IsFrozen()111    bool IsFrozen() { return Chase()->flags_ & FROZEN; }
112  
113    // ---------------------------------------------------------------------------
114    // Debugging.
115  #ifdef DEBUG
116    void Print(int n = 0);  // n = indentation; n < 0 => don't print recursively
117  #endif
118  
119    // ---------------------------------------------------------------------------
120    // Implementation.
121   private:
122    enum Flags {    // All flags are monotonic
123      NONE = 0,
124      VALUE = 1,    // This type describes a value
125      MODULE = 2,   // This type describes a module
126      FROZEN = 4    // This type is fully determined
127    };
128  
129    int flags_;
130    Interface* forward_;     // Unification link
131    ZoneHashMap* exports_;   // Module exports and their types (allocated lazily)
132  
Interface(int flags)133    explicit Interface(int flags)
134      : flags_(flags),
135        forward_(NULL),
136        exports_(NULL) {
137  #ifdef DEBUG
138      if (FLAG_print_interface_details)
139        PrintF("# Creating %p\n", static_cast<void*>(this));
140  #endif
141    }
142  
Chase()143    Interface* Chase() {
144      Interface* result = this;
145      while (result->forward_ != NULL) result = result->forward_;
146      if (result != this) forward_ = result;  // On-the-fly path compression.
147      return result;
148    }
149  
150    void DoAdd(void* name, uint32_t hash, Interface* interface, bool* ok);
151    void DoUnify(Interface* that, bool* ok);
152  };
153  
154  } }  // namespace v8::internal
155  
156  #endif  // V8_INTERFACE_H_
157