summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/code-assembler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/code-assembler.cc')
-rw-r--r--deps/v8/src/compiler/code-assembler.cc306
1 files changed, 213 insertions, 93 deletions
diff --git a/deps/v8/src/compiler/code-assembler.cc b/deps/v8/src/compiler/code-assembler.cc
index 93e384444e..4b1c211084 100644
--- a/deps/v8/src/compiler/code-assembler.cc
+++ b/deps/v8/src/compiler/code-assembler.cc
@@ -7,8 +7,8 @@
#include <ostream>
#include "src/code-factory.h"
+#include "src/compiler/backend/instruction-selector.h"
#include "src/compiler/graph.h"
-#include "src/compiler/instruction-selector.h"
#include "src/compiler/linkage.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/pipeline.h"
@@ -17,11 +17,11 @@
#include "src/frames.h"
#include "src/interface-descriptors.h"
#include "src/interpreter/bytecodes.h"
-#include "src/lsan.h"
#include "src/machine-type.h"
#include "src/macro-assembler.h"
+#include "src/memcopy.h"
#include "src/objects-inl.h"
-#include "src/utils.h"
+#include "src/objects/smi.h"
#include "src/zone/zone.h"
namespace v8 {
@@ -44,7 +44,7 @@ static_assert(
CodeAssemblerState::CodeAssemblerState(
Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor,
Code::Kind kind, const char* name, PoisoningMitigationLevel poisoning_level,
- uint32_t stub_key, int32_t builtin_index)
+ int32_t builtin_index)
// TODO(rmcilroy): Should we use Linkage::GetBytecodeDispatchDescriptor for
// bytecode handlers?
: CodeAssemblerState(
@@ -52,7 +52,7 @@ CodeAssemblerState::CodeAssemblerState(
Linkage::GetStubCallDescriptor(
zone, descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kNoFlags, Operator::kNoProperties),
- kind, name, poisoning_level, stub_key, builtin_index) {}
+ kind, name, poisoning_level, builtin_index) {}
CodeAssemblerState::CodeAssemblerState(Isolate* isolate, Zone* zone,
int parameter_count, Code::Kind kind,
@@ -66,13 +66,13 @@ CodeAssemblerState::CodeAssemblerState(Isolate* isolate, Zone* zone,
(kind == Code::BUILTIN ? CallDescriptor::kPushArgumentCount
: CallDescriptor::kNoFlags) |
CallDescriptor::kCanUseRoots),
- kind, name, poisoning_level, 0, builtin_index) {}
+ kind, name, poisoning_level, builtin_index) {}
CodeAssemblerState::CodeAssemblerState(Isolate* isolate, Zone* zone,
CallDescriptor* call_descriptor,
Code::Kind kind, const char* name,
PoisoningMitigationLevel poisoning_level,
- uint32_t stub_key, int32_t builtin_index)
+ int32_t builtin_index)
: raw_assembler_(new RawMachineAssembler(
isolate, new (zone) Graph(zone), call_descriptor,
MachineType::PointerRepresentation(),
@@ -80,7 +80,6 @@ CodeAssemblerState::CodeAssemblerState(Isolate* isolate, Zone* zone,
InstructionSelector::AlignmentRequirements(), poisoning_level)),
kind_(kind),
name_(name),
- stub_key_(stub_key),
builtin_index_(builtin_index),
code_generated_(false),
variables_(zone) {}
@@ -97,15 +96,16 @@ CodeAssembler::~CodeAssembler() = default;
void CodeAssemblerState::PrintCurrentBlock(std::ostream& os) {
raw_assembler_->PrintCurrentBlock(os);
}
+#endif
bool CodeAssemblerState::InsideBlock() { return raw_assembler_->InsideBlock(); }
-#endif
void CodeAssemblerState::SetInitialDebugInformation(const char* msg,
const char* file,
int line) {
#if DEBUG
AssemblerDebugInfo debug_info = {msg, file, line};
+ raw_assembler_->SetSourcePosition(file, line);
raw_assembler_->SetInitialDebugInformation(debug_info);
#endif // DEBUG
}
@@ -173,31 +173,15 @@ Handle<Code> CodeAssembler::GenerateCode(CodeAssemblerState* state,
DCHECK(!state->code_generated_);
RawMachineAssembler* rasm = state->raw_assembler_.get();
- Schedule* schedule = rasm->Export();
- JumpOptimizationInfo jump_opt;
- bool should_optimize_jumps =
- rasm->isolate()->serializer_enabled() && FLAG_turbo_rewrite_far_jumps;
+ Handle<Code> code;
+ Graph* graph = rasm->ExportForOptimization();
- Handle<Code> code =
- Pipeline::GenerateCodeForCodeStub(
- rasm->isolate(), rasm->call_descriptor(), rasm->graph(), schedule,
- state->kind_, state->name_, state->stub_key_, state->builtin_index_,
- should_optimize_jumps ? &jump_opt : nullptr, rasm->poisoning_level(),
- options)
- .ToHandleChecked();
-
- if (jump_opt.is_optimizable()) {
- jump_opt.set_optimizing();
-
- // Regenerate machine code
- code =
- Pipeline::GenerateCodeForCodeStub(
- rasm->isolate(), rasm->call_descriptor(), rasm->graph(), schedule,
- state->kind_, state->name_, state->stub_key_, state->builtin_index_,
- &jump_opt, rasm->poisoning_level(), options)
- .ToHandleChecked();
- }
+ code = Pipeline::GenerateCodeForCodeStub(
+ rasm->isolate(), rasm->call_descriptor(), graph,
+ rasm->source_positions(), state->kind_, state->name_,
+ state->builtin_index_, rasm->poisoning_level(), options)
+ .ToHandleChecked();
state->code_generated_ = true;
return code;
@@ -275,9 +259,9 @@ TNode<Number> CodeAssembler::NumberConstant(double value) {
}
}
-TNode<Smi> CodeAssembler::SmiConstant(Smi* value) {
- return UncheckedCast<Smi>(
- BitcastWordToTaggedSigned(IntPtrConstant(bit_cast<intptr_t>(value))));
+TNode<Smi> CodeAssembler::SmiConstant(Smi value) {
+ return UncheckedCast<Smi>(BitcastWordToTaggedSigned(
+ IntPtrConstant(static_cast<intptr_t>(value.ptr()))));
}
TNode<Smi> CodeAssembler::SmiConstant(int value) {
@@ -296,7 +280,9 @@ TNode<String> CodeAssembler::StringConstant(const char* str) {
}
TNode<Oddball> CodeAssembler::BooleanConstant(bool value) {
- return UncheckedCast<Oddball>(raw_assembler()->BooleanConstant(value));
+ Handle<Object> object = isolate()->factory()->ToBoolean(value);
+ return UncheckedCast<Oddball>(
+ raw_assembler()->HeapConstant(Handle<HeapObject>::cast(object)));
}
TNode<ExternalReference> CodeAssembler::ExternalConstant(
@@ -340,7 +326,7 @@ bool CodeAssembler::ToInt64Constant(Node* node, int64_t& out_value) {
return m.HasValue();
}
-bool CodeAssembler::ToSmiConstant(Node* node, Smi*& out_value) {
+bool CodeAssembler::ToSmiConstant(Node* node, Smi* out_value) {
if (node->opcode() == IrOpcode::kBitcastWordToTaggedSigned) {
node = node->InputAt(0);
}
@@ -349,7 +335,7 @@ bool CodeAssembler::ToSmiConstant(Node* node, Smi*& out_value) {
intptr_t value = m.Value();
// Make sure that the value is actually a smi
CHECK_EQ(0, value & ((static_cast<intptr_t>(1) << kSmiShiftSize) - 1));
- out_value = Smi::cast(bit_cast<Object*>(value));
+ *out_value = Smi(static_cast<Address>(value));
return true;
}
return false;
@@ -434,25 +420,13 @@ void CodeAssembler::Unreachable() {
raw_assembler()->Unreachable();
}
-void CodeAssembler::Comment(const char* format, ...) {
+void CodeAssembler::Comment(std::string str) {
if (!FLAG_code_comments) return;
- char buffer[4 * KB];
- StringBuilder builder(buffer, arraysize(buffer));
- va_list arguments;
- va_start(arguments, format);
- builder.AddFormattedList(format, arguments);
- va_end(arguments);
-
- // Copy the string before recording it in the assembler to avoid
- // issues when the stack allocated buffer goes out of scope.
- const int prefix_len = 2;
- int length = builder.position() + 1;
- char* copy = reinterpret_cast<char*>(malloc(length + prefix_len));
- LSAN_IGNORE_OBJECT(copy);
- MemCopy(copy + prefix_len, builder.Finalize(), length);
- copy[0] = ';';
- copy[1] = ' ';
- raw_assembler()->Comment(copy);
+ raw_assembler()->Comment(str);
+}
+
+void CodeAssembler::SetSourcePosition(const char* file, int line) {
+ raw_assembler()->SetSourcePosition(file, line);
}
void CodeAssembler::Bind(Label* label) { return label->Bind(); }
@@ -514,6 +488,23 @@ TNode<WordT> CodeAssembler::IntPtrAdd(SloppyTNode<WordT> left,
return UncheckedCast<WordT>(raw_assembler()->IntPtrAdd(left, right));
}
+TNode<IntPtrT> CodeAssembler::IntPtrDiv(TNode<IntPtrT> left,
+ TNode<IntPtrT> right) {
+ intptr_t left_constant;
+ bool is_left_constant = ToIntPtrConstant(left, left_constant);
+ intptr_t right_constant;
+ bool is_right_constant = ToIntPtrConstant(right, right_constant);
+ if (is_right_constant) {
+ if (is_left_constant) {
+ return IntPtrConstant(left_constant / right_constant);
+ }
+ if (base::bits::IsPowerOfTwo(right_constant)) {
+ return WordSar(left, WhichPowerOf2(right_constant));
+ }
+ }
+ return UncheckedCast<IntPtrT>(raw_assembler()->IntPtrDiv(left, right));
+}
+
TNode<WordT> CodeAssembler::IntPtrSub(SloppyTNode<WordT> left,
SloppyTNode<WordT> right) {
intptr_t left_constant;
@@ -965,8 +956,8 @@ Node* CodeAssembler::AtomicLoad(MachineType rep, Node* base, Node* offset) {
}
TNode<Object> CodeAssembler::LoadRoot(RootIndex root_index) {
- if (isolate()->heap()->RootCanBeTreatedAsConstant(root_index)) {
- Handle<Object> root = isolate()->heap()->root_handle(root_index);
+ if (RootsTable::IsImmortalImmovable(root_index)) {
+ Handle<Object> root = isolate()->root_handle(root_index);
if (root->IsSmi()) {
return SmiConstant(Smi::cast(*root));
} else {
@@ -977,11 +968,11 @@ TNode<Object> CodeAssembler::LoadRoot(RootIndex root_index) {
// TODO(jgruber): In theory we could generate better code for this by
// letting the macro assembler decide how to load from the roots list. In most
// cases, it would boil down to loading from a fixed kRootRegister offset.
- Node* roots_array_start =
- ExternalConstant(ExternalReference::roots_array_start(isolate()));
- size_t offset = static_cast<size_t>(root_index) * kPointerSize;
- return UncheckedCast<Object>(Load(MachineType::AnyTagged(), roots_array_start,
- IntPtrConstant(offset)));
+ Node* isolate_root =
+ ExternalConstant(ExternalReference::isolate_root(isolate()));
+ int offset = IsolateData::root_slot_offset(root_index);
+ return UncheckedCast<Object>(
+ Load(MachineType::AnyTagged(), isolate_root, IntPtrConstant(offset)));
}
Node* CodeAssembler::Store(Node* base, Node* value) {
@@ -989,15 +980,21 @@ Node* CodeAssembler::Store(Node* base, Node* value) {
kFullWriteBarrier);
}
-Node* CodeAssembler::Store(Node* base, Node* offset, Node* value) {
- return raw_assembler()->Store(MachineRepresentation::kTagged, base, offset,
- value, kFullWriteBarrier);
+void CodeAssembler::OptimizedStoreField(MachineRepresentation rep,
+ TNode<HeapObject> object, int offset,
+ Node* value,
+ WriteBarrierKind write_barrier) {
+ raw_assembler()->OptimizedStoreField(rep, object, offset, value,
+ write_barrier);
+}
+void CodeAssembler::OptimizedStoreMap(TNode<HeapObject> object,
+ TNode<Map> map) {
+ raw_assembler()->OptimizedStoreMap(object, map);
}
-Node* CodeAssembler::StoreWithMapWriteBarrier(Node* base, Node* offset,
- Node* value) {
+Node* CodeAssembler::Store(Node* base, Node* offset, Node* value) {
return raw_assembler()->Store(MachineRepresentation::kTagged, base, offset,
- value, kMapWriteBarrier);
+ value, kFullWriteBarrier);
}
Node* CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base,
@@ -1040,11 +1037,11 @@ Node* CodeAssembler::AtomicCompareExchange(MachineType type, Node* base,
}
Node* CodeAssembler::StoreRoot(RootIndex root_index, Node* value) {
- DCHECK(Heap::RootCanBeWrittenAfterInitialization(root_index));
- Node* roots_array_start =
- ExternalConstant(ExternalReference::roots_array_start(isolate()));
- size_t offset = static_cast<size_t>(root_index) * kPointerSize;
- return StoreNoWriteBarrier(MachineRepresentation::kTagged, roots_array_start,
+ DCHECK(!RootsTable::IsImmortalImmovable(root_index));
+ Node* isolate_root =
+ ExternalConstant(ExternalReference::isolate_root(isolate()));
+ int offset = IsolateData::root_slot_offset(root_index);
+ return StoreNoWriteBarrier(MachineRepresentation::kTagged, isolate_root,
IntPtrConstant(offset), value);
}
@@ -1053,7 +1050,7 @@ Node* CodeAssembler::Retain(Node* value) {
}
Node* CodeAssembler::Projection(int index, Node* value) {
- DCHECK(index < value->op()->ValueOutputCount());
+ DCHECK_LT(index, value->op()->ValueOutputCount());
return raw_assembler()->Projection(index, value);
}
@@ -1064,6 +1061,8 @@ void CodeAssembler::GotoIfException(Node* node, Label* if_exception,
return;
}
+ // No catch handlers should be active if we're using catch labels
+ DCHECK_EQ(state()->exception_handler_labels_.size(), 0);
DCHECK(!node->op()->HasProperty(Operator::kNoThrow));
Label success(this), exception(this, Label::kDeferred);
@@ -1081,6 +1080,38 @@ void CodeAssembler::GotoIfException(Node* node, Label* if_exception,
Goto(if_exception);
Bind(&success);
+ raw_assembler()->AddNode(raw_assembler()->common()->IfSuccess(), node);
+}
+
+TNode<HeapObject> CodeAssembler::OptimizedAllocate(TNode<IntPtrT> size,
+ PretenureFlag pretenure) {
+ return UncheckedCast<HeapObject>(
+ raw_assembler()->OptimizedAllocate(size, pretenure));
+}
+
+void CodeAssembler::HandleException(Node* node) {
+ if (state_->exception_handler_labels_.size() == 0) return;
+ CodeAssemblerExceptionHandlerLabel* label =
+ state_->exception_handler_labels_.back();
+
+ if (node->op()->HasProperty(Operator::kNoThrow)) {
+ return;
+ }
+
+ Label success(this), exception(this, Label::kDeferred);
+ success.MergeVariables();
+ exception.MergeVariables();
+
+ raw_assembler()->Continuations(node, success.label_, exception.label_);
+
+ Bind(&exception);
+ const Operator* op = raw_assembler()->common()->IfException();
+ Node* exception_value = raw_assembler()->AddNode(op, node, node);
+ label->AddInputs({UncheckedCast<Object>(exception_value)});
+ Goto(label->plain_label());
+
+ Bind(&success);
+ raw_assembler()->AddNode(raw_assembler()->common()->IfSuccess(), node);
}
namespace {
@@ -1133,6 +1164,7 @@ TNode<Object> CodeAssembler::CallRuntimeWithCEntryImpl(
CallPrologue();
Node* return_value =
raw_assembler()->CallN(call_descriptor, inputs.size(), inputs.data());
+ HandleException(return_value);
CallEpilogue();
return UncheckedCast<Object>(return_value);
}
@@ -1168,9 +1200,13 @@ void CodeAssembler::TailCallRuntimeWithCEntryImpl(
raw_assembler()->TailCallN(call_descriptor, inputs.size(), inputs.data());
}
-Node* CodeAssembler::CallStubN(const CallInterfaceDescriptor& descriptor,
+Node* CodeAssembler::CallStubN(StubCallMode call_mode,
+ const CallInterfaceDescriptor& descriptor,
size_t result_size, int input_count,
Node* const* inputs) {
+ DCHECK(call_mode == StubCallMode::kCallCodeObject ||
+ call_mode == StubCallMode::kCallBuiltinPointer);
+
// implicit nodes are target and optionally context.
int implicit_nodes = descriptor.HasContextParameter() ? 2 : 1;
DCHECK_LE(implicit_nodes, input_count);
@@ -1183,11 +1219,12 @@ Node* CodeAssembler::CallStubN(const CallInterfaceDescriptor& descriptor,
auto call_descriptor = Linkage::GetStubCallDescriptor(
zone(), descriptor, stack_parameter_count, CallDescriptor::kNoFlags,
- Operator::kNoProperties);
+ Operator::kNoProperties, call_mode);
CallPrologue();
Node* return_value =
raw_assembler()->CallN(call_descriptor, input_count, inputs);
+ HandleException(return_value);
CallEpilogue();
return return_value;
}
@@ -1212,10 +1249,14 @@ void CodeAssembler::TailCallStubImpl(const CallInterfaceDescriptor& descriptor,
raw_assembler()->TailCallN(call_descriptor, inputs.size(), inputs.data());
}
-Node* CodeAssembler::CallStubRImpl(const CallInterfaceDescriptor& descriptor,
- size_t result_size, SloppyTNode<Code> target,
+Node* CodeAssembler::CallStubRImpl(StubCallMode call_mode,
+ const CallInterfaceDescriptor& descriptor,
+ size_t result_size, Node* target,
SloppyTNode<Object> context,
std::initializer_list<Node*> args) {
+ DCHECK(call_mode == StubCallMode::kCallCodeObject ||
+ call_mode == StubCallMode::kCallBuiltinPointer);
+
constexpr size_t kMaxNumArgs = 10;
DCHECK_GE(kMaxNumArgs, args.size());
@@ -1226,7 +1267,8 @@ Node* CodeAssembler::CallStubRImpl(const CallInterfaceDescriptor& descriptor,
inputs.Add(context);
}
- return CallStubN(descriptor, result_size, inputs.size(), inputs.data());
+ return CallStubN(call_mode, descriptor, result_size, inputs.size(),
+ inputs.data());
}
Node* CodeAssembler::TailCallStubThenBytecodeDispatchImpl(
@@ -1484,6 +1526,10 @@ Factory* CodeAssembler::factory() const { return isolate()->factory(); }
Zone* CodeAssembler::zone() const { return raw_assembler()->zone(); }
+bool CodeAssembler::IsExceptionHandlerActive() const {
+ return state_->exception_handler_labels_.size() != 0;
+}
+
RawMachineAssembler* CodeAssembler::raw_assembler() const {
return state_->raw_assembler_.get();
}
@@ -1494,13 +1540,14 @@ RawMachineAssembler* CodeAssembler::raw_assembler() const {
// properly be verified.
class CodeAssemblerVariable::Impl : public ZoneObject {
public:
- explicit Impl(MachineRepresentation rep)
+ explicit Impl(MachineRepresentation rep, CodeAssemblerState::VariableId id)
:
#if DEBUG
debug_info_(AssemblerDebugInfo(nullptr, nullptr, -1)),
#endif
value_(nullptr),
- rep_(rep) {
+ rep_(rep),
+ var_id_(id) {
}
#if DEBUG
@@ -1511,13 +1558,25 @@ class CodeAssemblerVariable::Impl : public ZoneObject {
AssemblerDebugInfo debug_info_;
#endif // DEBUG
+ bool operator<(const CodeAssemblerVariable::Impl& other) const {
+ return var_id_ < other.var_id_;
+ }
Node* value_;
MachineRepresentation rep_;
+ CodeAssemblerState::VariableId var_id_;
};
+bool CodeAssemblerVariable::ImplComparator::operator()(
+ const CodeAssemblerVariable::Impl* a,
+ const CodeAssemblerVariable::Impl* b) const {
+ return *a < *b;
+}
+
CodeAssemblerVariable::CodeAssemblerVariable(CodeAssembler* assembler,
MachineRepresentation rep)
- : impl_(new (assembler->zone()) Impl(rep)), state_(assembler->state()) {
+ : impl_(new (assembler->zone())
+ Impl(rep, assembler->state()->NextVariableId())),
+ state_(assembler->state()) {
state_->variables_.insert(impl_);
}
@@ -1532,7 +1591,9 @@ CodeAssemblerVariable::CodeAssemblerVariable(CodeAssembler* assembler,
CodeAssemblerVariable::CodeAssemblerVariable(CodeAssembler* assembler,
AssemblerDebugInfo debug_info,
MachineRepresentation rep)
- : impl_(new (assembler->zone()) Impl(rep)), state_(assembler->state()) {
+ : impl_(new (assembler->zone())
+ Impl(rep, assembler->state()->NextVariableId())),
+ state_(assembler->state()) {
impl_->set_debug_info(debug_info);
state_->variables_.insert(impl_);
}
@@ -1677,6 +1738,7 @@ void CodeAssemblerLabel::Bind(AssemblerDebugInfo debug_info) {
<< "\n# previous: " << *label_->block();
FATAL("%s", str.str().c_str());
}
+ state_->raw_assembler_->SetSourcePosition(debug_info.file, debug_info.line);
state_->raw_assembler_->Bind(label_, debug_info);
UpdateVariablesAfterBind();
}
@@ -1791,21 +1853,79 @@ const std::vector<Node*>& CodeAssemblerParameterizedLabelBase::CreatePhis(
return phi_nodes_;
}
+void CodeAssemblerState::PushExceptionHandler(
+ CodeAssemblerExceptionHandlerLabel* label) {
+ exception_handler_labels_.push_back(label);
+}
+
+void CodeAssemblerState::PopExceptionHandler() {
+ exception_handler_labels_.pop_back();
+}
+
+CodeAssemblerScopedExceptionHandler::CodeAssemblerScopedExceptionHandler(
+ CodeAssembler* assembler, CodeAssemblerExceptionHandlerLabel* label)
+ : has_handler_(label != nullptr),
+ assembler_(assembler),
+ compatibility_label_(nullptr),
+ exception_(nullptr) {
+ if (has_handler_) {
+ assembler_->state()->PushExceptionHandler(label);
+ }
+}
+
+CodeAssemblerScopedExceptionHandler::CodeAssemblerScopedExceptionHandler(
+ CodeAssembler* assembler, CodeAssemblerLabel* label,
+ TypedCodeAssemblerVariable<Object>* exception)
+ : has_handler_(label != nullptr),
+ assembler_(assembler),
+ compatibility_label_(label),
+ exception_(exception) {
+ if (has_handler_) {
+ label_ = base::make_unique<CodeAssemblerExceptionHandlerLabel>(
+ assembler, CodeAssemblerLabel::kDeferred);
+ assembler_->state()->PushExceptionHandler(label_.get());
+ }
+}
+
+CodeAssemblerScopedExceptionHandler::~CodeAssemblerScopedExceptionHandler() {
+ if (has_handler_) {
+ assembler_->state()->PopExceptionHandler();
+ }
+ if (label_ && label_->is_used()) {
+ CodeAssembler::Label skip(assembler_);
+ bool inside_block = assembler_->state()->InsideBlock();
+ if (inside_block) {
+ assembler_->Goto(&skip);
+ }
+ TNode<Object> e;
+ assembler_->Bind(label_.get(), &e);
+ *exception_ = e;
+ assembler_->Goto(compatibility_label_);
+ if (inside_block) {
+ assembler_->Bind(&skip);
+ }
+ }
+}
+
} // namespace compiler
-Smi* CheckObjectType(Object* value, Smi* type, String* location) {
+Address CheckObjectType(Address raw_value, Address raw_type,
+ Address raw_location) {
#ifdef DEBUG
+ Object value(raw_value);
+ Smi type(raw_type);
+ String location = String::cast(Object(raw_location));
const char* expected;
switch (static_cast<ObjectType>(type->value())) {
-#define TYPE_CASE(Name) \
- case ObjectType::k##Name: \
- if (value->Is##Name()) return Smi::FromInt(0); \
- expected = #Name; \
+#define TYPE_CASE(Name) \
+ case ObjectType::k##Name: \
+ if (value->Is##Name()) return Smi::FromInt(0).ptr(); \
+ expected = #Name; \
break;
-#define TYPE_STRUCT_CASE(NAME, Name, name) \
- case ObjectType::k##Name: \
- if (value->Is##Name()) return Smi::FromInt(0); \
- expected = #Name; \
+#define TYPE_STRUCT_CASE(NAME, Name, name) \
+ case ObjectType::k##Name: \
+ if (value->Is##Name()) return Smi::FromInt(0).ptr(); \
+ expected = #Name; \
break;
TYPE_CASE(Object)