blob: b8888868ec0b90f72542a3832a914abaa7f5438e [file] [log] [blame]
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_IC_HANDLER_CONFIGURATION_H_
#define V8_IC_HANDLER_CONFIGURATION_H_
#include "src/common/globals.h"
#include "src/handles/maybe-handles.h"
#include "src/objects/data-handler.h"
#include "src/objects/elements-kind.h"
#include "src/objects/field-index.h"
#include "src/objects/objects.h"
#include "src/utils/utils.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
class JSProxy;
// A set of bit fields representing Smi handlers for loads and a HeapObject
// that represents load handlers that can't be encoded in a Smi.
// TODO(ishell): move to load-handler.h
class LoadHandler final : public DataHandler {
public:
DECL_CAST(LoadHandler)
DECL_PRINTER(LoadHandler)
DECL_VERIFIER(LoadHandler)
enum Kind {
kElement,
kIndexedString,
kNormal,
kGlobal,
kField,
kConstant,
kAccessor,
kNativeDataProperty,
kApiGetter,
kApiGetterHolderIsPrototype,
kInterceptor,
kProxy,
kNonExistent,
kModuleExport
};
class KindBits : public BitField<Kind, 0, 4> {};
// Defines whether access rights check should be done on receiver object.
// Applicable to named property kinds only when loading value from prototype
// chain. Ignored when loading from holder.
class DoAccessCheckOnReceiverBits
: public BitField<bool, KindBits::kNext, 1> {};
// Defines whether a lookup should be done on receiver object before
// proceeding to the prototype chain. Applicable to named property kinds only
// when loading value from prototype chain. Ignored when loading from holder.
class LookupOnReceiverBits
: public BitField<bool, DoAccessCheckOnReceiverBits::kNext, 1> {};
//
// Encoding when KindBits contains kForConstants.
//
// Index of a value entry in the descriptor array.
class DescriptorBits : public BitField<unsigned, LookupOnReceiverBits::kNext,
kDescriptorIndexBitCount> {};
// Make sure we don't overflow the smi.
STATIC_ASSERT(DescriptorBits::kNext <= kSmiValueSize);
//
// Encoding when KindBits contains kField.
//
class IsInobjectBits : public BitField<bool, LookupOnReceiverBits::kNext, 1> {
};
class IsDoubleBits : public BitField<bool, IsInobjectBits::kNext, 1> {};
// +1 here is to cover all possible JSObject header sizes.
class FieldIndexBits : public BitField<unsigned, IsDoubleBits::kNext,
kDescriptorIndexBitCount + 1> {};
// Make sure we don't overflow the smi.
STATIC_ASSERT(FieldIndexBits::kNext <= kSmiValueSize);
//
// Encoding when KindBits contains kElement or kIndexedString.
//
class AllowOutOfBoundsBits
: public BitField<bool, LookupOnReceiverBits::kNext, 1> {};
//
// Encoding when KindBits contains kElement.
//
class IsJsArrayBits : public BitField<bool, AllowOutOfBoundsBits::kNext, 1> {
};
class ConvertHoleBits : public BitField<bool, IsJsArrayBits::kNext, 1> {};
class ElementsKindBits
: public BitField<ElementsKind, ConvertHoleBits::kNext, 8> {};
// Make sure we don't overflow the smi.
STATIC_ASSERT(ElementsKindBits::kNext <= kSmiValueSize);
//
// Encoding when KindBits contains kModuleExport.
//
class ExportsIndexBits
: public BitField<unsigned, LookupOnReceiverBits::kNext,
kSmiValueSize - LookupOnReceiverBits::kNext> {};
// Decodes kind from Smi-handler.
static inline Kind GetHandlerKind(Smi smi_handler);
// Creates a Smi-handler for loading a property from a slow object.
static inline Handle<Smi> LoadNormal(Isolate* isolate);
// Creates a Smi-handler for loading a property from a global object.
static inline Handle<Smi> LoadGlobal(Isolate* isolate);
// Creates a Smi-handler for loading a property from an object with an
// interceptor.
static inline Handle<Smi> LoadInterceptor(Isolate* isolate);
// Creates a Smi-handler for loading a field from fast object.
static inline Handle<Smi> LoadField(Isolate* isolate, FieldIndex field_index);
// Creates a Smi-handler for loading a constant from fast object.
static inline Handle<Smi> LoadConstant(Isolate* isolate, int descriptor);
// Creates a Smi-handler for calling a getter on a fast object.
static inline Handle<Smi> LoadAccessor(Isolate* isolate, int descriptor);
// Creates a Smi-handler for calling a getter on a proxy.
static inline Handle<Smi> LoadProxy(Isolate* isolate);
// Creates a Smi-handler for loading a native data property from fast object.
static inline Handle<Smi> LoadNativeDataProperty(Isolate* isolate,
int descriptor);
// Creates a Smi-handler for calling a native getter on a fast object.
static inline Handle<Smi> LoadApiGetter(Isolate* isolate,
bool holder_is_receiver);
// Creates a Smi-handler for loading a Module export.
// |index| is the index to the "value" slot in the Module's "exports"
// dictionary.
static inline Handle<Smi> LoadModuleExport(Isolate* isolate, int index);
// Creates a data handler that represents a load of a non-existent property.
// {holder} is the object from which the property is loaded. If no holder is
// needed (e.g., for "nonexistent"), null_value() may be passed in.
static Handle<Object> LoadFullChain(Isolate* isolate,
Handle<Map> receiver_map,
const MaybeObjectHandle& holder,
Handle<Smi> smi_handler);
// Creates a data handler that represents a prototype chain check followed
// by given Smi-handler that encoded a load from the holder.
// Can be used only if GetPrototypeCheckCount() returns non negative value.
static Handle<Object> LoadFromPrototype(
Isolate* isolate, Handle<Map> receiver_map, Handle<JSReceiver> holder,
Handle<Smi> smi_handler,
MaybeObjectHandle maybe_data1 = MaybeObjectHandle(),
MaybeObjectHandle maybe_data2 = MaybeObjectHandle());
// Creates a Smi-handler for loading a non-existent property. Works only as
// a part of prototype chain check.
static inline Handle<Smi> LoadNonExistent(Isolate* isolate);
// Creates a Smi-handler for loading an element.
static inline Handle<Smi> LoadElement(Isolate* isolate,
ElementsKind elements_kind,
bool convert_hole_to_undefined,
bool is_js_array,
KeyedAccessLoadMode load_mode);
// Creates a Smi-handler for loading from a String.
static inline Handle<Smi> LoadIndexedString(Isolate* isolate,
KeyedAccessLoadMode load_mode);
// Decodes the KeyedAccessLoadMode from a {handler}.
static KeyedAccessLoadMode GetKeyedAccessLoadMode(MaybeObject handler);
OBJECT_CONSTRUCTORS(LoadHandler, DataHandler);
};
// A set of bit fields representing Smi handlers for stores and a HeapObject
// that represents store handlers that can't be encoded in a Smi.
// TODO(ishell): move to store-handler.h
class StoreHandler final : public DataHandler {
public:
DECL_CAST(StoreHandler)
DECL_PRINTER(StoreHandler)
DECL_VERIFIER(StoreHandler)
enum Kind {
kElement,
kField,
kConstField,
kAccessor,
kNativeDataProperty,
kApiSetter,
kApiSetterHolderIsPrototype,
kGlobalProxy,
kNormal,
kProxy,
kKindsNumber // Keep last
};
class KindBits : public BitField<Kind, 0, 4> {};
enum FieldRepresentation { kSmi, kDouble, kHeapObject, kTagged };
// Applicable to kGlobalProxy, kProxy kinds.
// Defines whether access rights check should be done on receiver object.
class DoAccessCheckOnReceiverBits
: public BitField<bool, KindBits::kNext, 1> {};
// Defines whether a lookup should be done on receiver object before
// proceeding to the prototype chain. Applicable to named property kinds only
// when storing through prototype chain. Ignored when storing to holder.
class LookupOnReceiverBits
: public BitField<bool, DoAccessCheckOnReceiverBits::kNext, 1> {};
// Applicable to kField, kTransitionToField and kTransitionToConstant
// kinds.
// Index of a value entry in the descriptor array.
class DescriptorBits : public BitField<unsigned, LookupOnReceiverBits::kNext,
kDescriptorIndexBitCount> {};
//
// Encoding when KindBits contains kTransitionToConstant.
//
// Make sure we don't overflow the smi.
STATIC_ASSERT(DescriptorBits::kNext <= kSmiValueSize);
//
// Encoding when KindBits contains kField or kTransitionToField.
//
class IsInobjectBits : public BitField<bool, DescriptorBits::kNext, 1> {};
class FieldRepresentationBits
: public BitField<FieldRepresentation, IsInobjectBits::kNext, 2> {};
// +1 here is to cover all possible JSObject header sizes.
class FieldIndexBits
: public BitField<unsigned, FieldRepresentationBits::kNext,
kDescriptorIndexBitCount + 1> {};
// Make sure we don't overflow the smi.
STATIC_ASSERT(FieldIndexBits::kNext <= kSmiValueSize);
// Creates a Smi-handler for storing a field to fast object.
static inline Handle<Smi> StoreField(Isolate* isolate, int descriptor,
FieldIndex field_index,
PropertyConstness constness,
Representation representation);
static MaybeObjectHandle StoreTransition(Isolate* isolate,
Handle<Map> transition_map);
// Creates a Smi-handler for storing a native data property on a fast object.
static inline Handle<Smi> StoreNativeDataProperty(Isolate* isolate,
int descriptor);
// Creates a Smi-handler for calling a setter on a fast object.
static inline Handle<Smi> StoreAccessor(Isolate* isolate, int descriptor);
// Creates a Smi-handler for calling a native setter on a fast object.
static inline Handle<Smi> StoreApiSetter(Isolate* isolate,
bool holder_is_receiver);
static Handle<Object> StoreThroughPrototype(
Isolate* isolate, Handle<Map> receiver_map, Handle<JSReceiver> holder,
Handle<Smi> smi_handler,
MaybeObjectHandle maybe_data1 = MaybeObjectHandle(),
MaybeObjectHandle maybe_data2 = MaybeObjectHandle());
static Handle<Object> StoreElementTransition(Isolate* isolate,
Handle<Map> receiver_map,
Handle<Map> transition,
KeyedAccessStoreMode store_mode);
static Handle<Object> StoreProxy(Isolate* isolate, Handle<Map> receiver_map,
Handle<JSProxy> proxy,
Handle<JSReceiver> receiver);
// Creates a handler for storing a property to the property cell of a global
// object.
static MaybeObjectHandle StoreGlobal(Handle<PropertyCell> cell);
// Creates a Smi-handler for storing a property to a global proxy object.
static inline Handle<Smi> StoreGlobalProxy(Isolate* isolate);
// Creates a Smi-handler for storing a property to a slow object.
static inline Handle<Smi> StoreNormal(Isolate* isolate);
// Creates a Smi-handler for storing a property on a proxy.
static inline Handle<Smi> StoreProxy(Isolate* isolate);
private:
static inline Handle<Smi> StoreField(Isolate* isolate, Kind kind,
int descriptor, FieldIndex field_index,
Representation representation);
OBJECT_CONSTRUCTORS(StoreHandler, DataHandler);
};
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_IC_HANDLER_CONFIGURATION_H_