blob: 679e6ea95ce161255e1c8d29851c9bccbcabbdce [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_INL_H_
#define V8_IC_HANDLER_CONFIGURATION_INL_H_
#include "src/builtins/builtins.h"
#include "src/execution/isolate.h"
#include "src/handles/handles-inl.h"
#include "src/ic/handler-configuration.h"
#include "src/objects/data-handler-inl.h"
#include "src/objects/field-index-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/smi.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
OBJECT_CONSTRUCTORS_IMPL(LoadHandler, DataHandler)
CAST_ACCESSOR(LoadHandler)
// Decodes kind from Smi-handler.
LoadHandler::Kind LoadHandler::GetHandlerKind(Smi smi_handler) {
return KindBits::decode(smi_handler.value());
}
Handle<Smi> LoadHandler::LoadNormal(Isolate* isolate) {
int config = KindBits::encode(Kind::kNormal);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadGlobal(Isolate* isolate) {
int config = KindBits::encode(Kind::kGlobal);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadInterceptor(Isolate* isolate) {
int config = KindBits::encode(Kind::kInterceptor);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadSlow(Isolate* isolate) {
int config = KindBits::encode(Kind::kSlow);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadField(Isolate* isolate, FieldIndex field_index) {
int config = KindBits::encode(Kind::kField) |
IsInobjectBits::encode(field_index.is_inobject()) |
IsDoubleBits::encode(field_index.is_double()) |
FieldIndexBits::encode(field_index.index());
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadWasmStructField(Isolate* isolate,
WasmValueType type, int offset) {
int config = KindBits::encode(Kind::kField) | IsWasmStructBits::encode(true) |
WasmFieldTypeBits::encode(type) |
WasmFieldOffsetBits::encode(offset);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadConstantFromPrototype(Isolate* isolate) {
int config = KindBits::encode(Kind::kConstantFromPrototype);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadAccessorFromPrototype(Isolate* isolate) {
int config = KindBits::encode(Kind::kAccessorFromPrototype);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadProxy(Isolate* isolate) {
int config = KindBits::encode(Kind::kProxy);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadNativeDataProperty(Isolate* isolate,
int descriptor) {
int config = KindBits::encode(Kind::kNativeDataProperty) |
DescriptorBits::encode(descriptor);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadApiGetter(Isolate* isolate,
bool holder_is_receiver) {
int config =
KindBits::encode(holder_is_receiver ? Kind::kApiGetter
: Kind::kApiGetterHolderIsPrototype);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadModuleExport(Isolate* isolate, int index) {
int config =
KindBits::encode(Kind::kModuleExport) | ExportsIndexBits::encode(index);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadNonExistent(Isolate* isolate) {
int config = KindBits::encode(Kind::kNonExistent);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadElement(Isolate* isolate,
ElementsKind elements_kind,
bool convert_hole_to_undefined,
bool is_js_array,
KeyedAccessLoadMode load_mode) {
int config =
KindBits::encode(Kind::kElement) |
AllowOutOfBoundsBits::encode(load_mode == LOAD_IGNORE_OUT_OF_BOUNDS) |
ElementsKindBits::encode(elements_kind) |
ConvertHoleBits::encode(convert_hole_to_undefined) |
IsJsArrayBits::encode(is_js_array);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadIndexedString(Isolate* isolate,
KeyedAccessLoadMode load_mode) {
int config =
KindBits::encode(Kind::kIndexedString) |
AllowOutOfBoundsBits::encode(load_mode == LOAD_IGNORE_OUT_OF_BOUNDS);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadWasmArrayElement(Isolate* isolate,
WasmValueType type) {
int config = KindBits::encode(Kind::kElement) |
IsWasmArrayBits::encode(true) | WasmArrayTypeBits::encode(type);
return handle(Smi::FromInt(config), isolate);
}
OBJECT_CONSTRUCTORS_IMPL(StoreHandler, DataHandler)
CAST_ACCESSOR(StoreHandler)
Handle<Smi> StoreHandler::StoreGlobalProxy(Isolate* isolate) {
int config = KindBits::encode(Kind::kGlobalProxy);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> StoreHandler::StoreNormal(Isolate* isolate) {
int config = KindBits::encode(Kind::kNormal);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> StoreHandler::StoreInterceptor(Isolate* isolate) {
int config = KindBits::encode(Kind::kInterceptor);
return handle(Smi::FromInt(config), isolate);
}
Handle<Code> StoreHandler::StoreSloppyArgumentsBuiltin(
Isolate* isolate, KeyedAccessStoreMode mode) {
switch (mode) {
case STANDARD_STORE:
return BUILTIN_CODE(isolate, KeyedStoreIC_SloppyArguments_Standard);
case STORE_AND_GROW_HANDLE_COW:
return BUILTIN_CODE(
isolate, KeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW);
case STORE_IGNORE_OUT_OF_BOUNDS:
return BUILTIN_CODE(isolate,
KeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB);
case STORE_HANDLE_COW:
return BUILTIN_CODE(isolate,
KeyedStoreIC_SloppyArguments_NoTransitionHandleCOW);
default:
UNREACHABLE();
}
}
Handle<Code> StoreHandler::StoreFastElementBuiltin(Isolate* isolate,
KeyedAccessStoreMode mode) {
switch (mode) {
case STANDARD_STORE:
return BUILTIN_CODE(isolate, StoreFastElementIC_Standard);
case STORE_AND_GROW_HANDLE_COW:
return BUILTIN_CODE(isolate,
StoreFastElementIC_GrowNoTransitionHandleCOW);
case STORE_IGNORE_OUT_OF_BOUNDS:
return BUILTIN_CODE(isolate, StoreFastElementIC_NoTransitionIgnoreOOB);
case STORE_HANDLE_COW:
return BUILTIN_CODE(isolate, StoreFastElementIC_NoTransitionHandleCOW);
default:
UNREACHABLE();
}
}
Handle<Code> StoreHandler::ElementsTransitionAndStoreBuiltin(
Isolate* isolate, KeyedAccessStoreMode mode) {
switch (mode) {
case STANDARD_STORE:
return BUILTIN_CODE(isolate, ElementsTransitionAndStore_Standard);
case STORE_AND_GROW_HANDLE_COW:
return BUILTIN_CODE(isolate,
ElementsTransitionAndStore_GrowNoTransitionHandleCOW);
case STORE_IGNORE_OUT_OF_BOUNDS:
return BUILTIN_CODE(isolate,
ElementsTransitionAndStore_NoTransitionIgnoreOOB);
case STORE_HANDLE_COW:
return BUILTIN_CODE(isolate,
ElementsTransitionAndStore_NoTransitionHandleCOW);
default:
UNREACHABLE();
}
}
Handle<Smi> StoreHandler::StoreSlow(Isolate* isolate,
KeyedAccessStoreMode store_mode) {
int config = KindBits::encode(Kind::kSlow) |
KeyedAccessStoreModeBits::encode(store_mode);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> StoreHandler::StoreProxy(Isolate* isolate) {
return handle(StoreProxy(), isolate);
}
Smi StoreHandler::StoreProxy() {
int config = KindBits::encode(Kind::kProxy);
return Smi::FromInt(config);
}
Handle<Smi> StoreHandler::StoreField(Isolate* isolate, Kind kind,
int descriptor, FieldIndex field_index,
Representation representation) {
DCHECK(!representation.IsNone());
DCHECK(kind == Kind::kField || kind == Kind::kConstField ||
kind == Kind::kSharedStructField);
int config = KindBits::encode(kind) |
IsInobjectBits::encode(field_index.is_inobject()) |
RepresentationBits::encode(representation.kind()) |
DescriptorBits::encode(descriptor) |
FieldIndexBits::encode(field_index.index());
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> StoreHandler::StoreField(Isolate* isolate, int descriptor,
FieldIndex field_index,
PropertyConstness constness,
Representation representation) {
Kind kind = constness == PropertyConstness::kMutable ? Kind::kField
: Kind::kConstField;
return StoreField(isolate, kind, descriptor, field_index, representation);
}
Handle<Smi> StoreHandler::StoreSharedStructField(
Isolate* isolate, int descriptor, FieldIndex field_index,
Representation representation) {
DCHECK(representation.Equals(Representation::Tagged()));
return StoreField(isolate, Kind::kSharedStructField, descriptor, field_index,
representation);
}
Handle<Smi> StoreHandler::StoreNativeDataProperty(Isolate* isolate,
int descriptor) {
int config = KindBits::encode(Kind::kNativeDataProperty) |
DescriptorBits::encode(descriptor);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> StoreHandler::StoreAccessor(Isolate* isolate, int descriptor) {
int config =
KindBits::encode(Kind::kAccessor) | DescriptorBits::encode(descriptor);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> StoreHandler::StoreApiSetter(Isolate* isolate,
bool holder_is_receiver) {
int config =
KindBits::encode(holder_is_receiver ? Kind::kApiSetter
: Kind::kApiSetterHolderIsPrototype);
return handle(Smi::FromInt(config), isolate);
}
inline const char* WasmValueType2String(WasmValueType type) {
switch (type) {
case WasmValueType::kI8:
return "i8";
case WasmValueType::kI16:
return "i16";
case WasmValueType::kI32:
return "i32";
case WasmValueType::kU32:
return "u32";
case WasmValueType::kI64:
return "i64";
case WasmValueType::kF32:
return "f32";
case WasmValueType::kF64:
return "f64";
case WasmValueType::kS128:
return "s128";
case WasmValueType::kRef:
return "Ref";
case WasmValueType::kRefNull:
return "RefNull";
case WasmValueType::kNumTypes:
return "???";
}
}
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_IC_HANDLER_CONFIGURATION_INL_H_