summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/wasm-compiler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/wasm-compiler.cc')
-rw-r--r--deps/v8/src/compiler/wasm-compiler.cc715
1 files changed, 499 insertions, 216 deletions
diff --git a/deps/v8/src/compiler/wasm-compiler.cc b/deps/v8/src/compiler/wasm-compiler.cc
index 2da7177ece..28f9943e59 100644
--- a/deps/v8/src/compiler/wasm-compiler.cc
+++ b/deps/v8/src/compiler/wasm-compiler.cc
@@ -25,12 +25,11 @@
#include "src/compiler/graph-visualizer.h"
#include "src/compiler/graph.h"
#include "src/compiler/int64-lowering.h"
-#include "src/compiler/js-graph.h"
-#include "src/compiler/js-operator.h"
#include "src/compiler/linkage.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-origin-table.h"
+#include "src/compiler/node-properties.h"
#include "src/compiler/pipeline.h"
#include "src/compiler/simd-scalar-lowering.h"
#include "src/compiler/zone-stats.h"
@@ -259,25 +258,25 @@ Node* WasmGraphBuilder::Merge(unsigned count, Node** controls) {
Node* WasmGraphBuilder::Phi(wasm::ValueType type, unsigned count, Node** vals,
Node* control) {
DCHECK(IrOpcode::IsMergeOpcode(control->opcode()));
- Node** buf = Realloc(vals, count, count + 1);
+ Vector<Node*> buf = Realloc(vals, count, count + 1);
buf[count] = control;
return graph()->NewNode(
mcgraph()->common()->Phi(wasm::ValueTypes::MachineRepresentationFor(type),
count),
- count + 1, buf);
+ count + 1, buf.begin());
}
Node* WasmGraphBuilder::EffectPhi(unsigned count, Node** effects,
Node* control) {
DCHECK(IrOpcode::IsMergeOpcode(control->opcode()));
- Node** buf = Realloc(effects, count, count + 1);
+ Vector<Node*> buf = Realloc(effects, count, count + 1);
buf[count] = control;
return graph()->NewNode(mcgraph()->common()->EffectPhi(count), count + 1,
- buf);
+ buf.begin());
}
Node* WasmGraphBuilder::RefNull() {
- Node* isolate_root = LOAD_INSTANCE_FIELD(IsolateRoot, MachineType::Pointer());
+ Node* isolate_root = BuildLoadIsolateRoot();
return LOAD_TAGGED_POINTER(
isolate_root, IsolateData::root_slot_offset(RootIndex::kNullValue));
}
@@ -291,10 +290,17 @@ Node* WasmGraphBuilder::RefFunc(uint32_t function_index) {
}
Node* WasmGraphBuilder::NoContextConstant() {
- // TODO(titzer): avoiding a dependency on JSGraph here. Refactor.
return mcgraph()->IntPtrConstant(0);
}
+Node* WasmGraphBuilder::BuildLoadIsolateRoot() {
+ // The IsolateRoot is loaded from the instance node so that the generated
+ // code is Isolate independent. This can be overridden by setting a specific
+ // node in {isolate_root_node_} beforehand.
+ if (isolate_root_node_.is_set()) return isolate_root_node_.get();
+ return LOAD_INSTANCE_FIELD(IsolateRoot, MachineType::Pointer());
+}
+
Node* WasmGraphBuilder::Uint32Constant(uint32_t value) {
return mcgraph()->Uint32Constant(value);
}
@@ -320,10 +326,6 @@ void WasmGraphBuilder::StackCheck(wasm::WasmCodePosition position,
if (effect == nullptr) effect = effect_;
if (control == nullptr) control = control_;
- // This instruction sequence is matched in the instruction selector to
- // load the stack pointer directly on some platforms. Hence, when modifying
- // please also fix WasmStackCheckMatcher in node-matchers.h
-
Node* limit_address = graph()->NewNode(
mcgraph()->machine()->Load(MachineType::Pointer()), instance_node_.get(),
mcgraph()->Int32Constant(WASM_INSTANCE_OBJECT_OFFSET(StackLimitAddress)),
@@ -332,10 +334,9 @@ void WasmGraphBuilder::StackCheck(wasm::WasmCodePosition position,
mcgraph()->machine()->Load(MachineType::Pointer()), limit_address,
mcgraph()->IntPtrConstant(0), limit_address, *control);
*effect = limit;
- Node* pointer = graph()->NewNode(mcgraph()->machine()->LoadStackPointer());
Node* check =
- graph()->NewNode(mcgraph()->machine()->UintLessThan(), limit, pointer);
+ graph()->NewNode(mcgraph()->machine()->StackPointerGreaterThan(), limit);
Diamond stack_check(graph(), mcgraph()->common(), check, BranchHint::kTrue);
stack_check.Chain(*control);
@@ -1126,12 +1127,13 @@ Node* WasmGraphBuilder::IfDefault(Node* sw) {
return graph()->NewNode(mcgraph()->common()->IfDefault(), sw);
}
-Node* WasmGraphBuilder::Return(unsigned count, Node** vals) {
+Node* WasmGraphBuilder::Return(Vector<Node*> vals) {
static const int kStackAllocatedNodeBufferSize = 8;
Node* stack_buffer[kStackAllocatedNodeBufferSize];
std::vector<Node*> heap_buffer;
Node** buf = stack_buffer;
+ unsigned count = static_cast<unsigned>(vals.size());
if (count + 3 > kStackAllocatedNodeBufferSize) {
heap_buffer.resize(count + 3);
buf = heap_buffer.data();
@@ -1139,7 +1141,7 @@ Node* WasmGraphBuilder::Return(unsigned count, Node** vals) {
buf[0] = mcgraph()->Int32Constant(0);
if (count > 0) {
- memcpy(buf + 1, vals, sizeof(void*) * count);
+ memcpy(buf + 1, vals.begin(), sizeof(void*) * count);
}
buf[count + 1] = Effect();
buf[count + 2] = Control();
@@ -1150,11 +1152,9 @@ Node* WasmGraphBuilder::Return(unsigned count, Node** vals) {
return ret;
}
-Node* WasmGraphBuilder::ReturnVoid() { return Return(0, nullptr); }
-
Node* WasmGraphBuilder::Unreachable(wasm::WasmCodePosition position) {
TrapIfFalse(wasm::TrapReason::kTrapUnreachable, Int32Constant(0), position);
- ReturnVoid();
+ Return(Vector<Node*>{});
return nullptr;
}
@@ -2295,13 +2295,13 @@ Node* WasmGraphBuilder::GetExceptionTag(Node* except_obj) {
return BuildCallToRuntime(Runtime::kWasmExceptionGetTag, &except_obj, 1);
}
-Node** WasmGraphBuilder::GetExceptionValues(
+Vector<Node*> WasmGraphBuilder::GetExceptionValues(
Node* except_obj, const wasm::WasmException* exception) {
Node* values_array =
BuildCallToRuntime(Runtime::kWasmExceptionGetValues, &except_obj, 1);
uint32_t index = 0;
const wasm::WasmExceptionSig* sig = exception->sig;
- Node** values = Buffer(sig->parameter_count());
+ Vector<Node*> values = Buffer(sig->parameter_count());
for (size_t i = 0; i < sig->parameter_count(); ++i) {
Node* value;
switch (sig->GetParam(i)) {
@@ -2695,7 +2695,7 @@ Node* WasmGraphBuilder::BuildCallNode(wasm::FunctionSig* sig, Node** args,
const size_t count = 1 + params + extra;
// Reallocate the buffer to make space for extra inputs.
- args = Realloc(args, 1 + params, count);
+ args = Realloc(args, 1 + params, count).begin();
// Make room for the instance_node parameter at index 1, just after code.
memmove(&args[2], &args[1], params * sizeof(Node*));
@@ -2725,7 +2725,7 @@ Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args,
size_t ret_count = sig->return_count();
if (ret_count == 0) return call; // No return value.
- *rets = Buffer(ret_count);
+ *rets = Buffer(ret_count).begin();
if (ret_count == 1) {
// Only a single return value.
(*rets)[0] = call;
@@ -3183,12 +3183,12 @@ Node* WasmGraphBuilder::CreateOrMergeIntoPhi(MachineRepresentation rep,
} else if (tnode != fnode) {
uint32_t count = merge->InputCount();
// + 1 for the merge node.
- Node** vals = Buffer(count + 1);
+ Vector<Node*> vals = Buffer(count + 1);
for (uint32_t j = 0; j < count - 1; j++) vals[j] = tnode;
vals[count - 1] = fnode;
vals[count] = merge;
return graph()->NewNode(mcgraph()->common()->Phi(rep, count), count + 1,
- vals);
+ vals.begin());
}
return tnode;
}
@@ -3199,12 +3199,12 @@ Node* WasmGraphBuilder::CreateOrMergeIntoEffectPhi(Node* merge, Node* tnode,
AppendToPhi(tnode, fnode);
} else if (tnode != fnode) {
uint32_t count = merge->InputCount();
- Node** effects = Buffer(count);
+ Vector<Node*> effects = Buffer(count);
for (uint32_t j = 0; j < count - 1; j++) {
effects[j] = tnode;
}
effects[count - 1] = fnode;
- tnode = EffectPhi(count, effects, merge);
+ tnode = EffectPhi(count, effects.begin(), merge);
}
return tnode;
}
@@ -3326,11 +3326,14 @@ Node* WasmGraphBuilder::BuildCallToRuntimeWithContext(
auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
mcgraph()->zone(), f, fun->nargs, Operator::kNoProperties,
CallDescriptor::kNoFlags);
- // The CEntryStub is loaded from the instance_node so that generated code is
+ // The CEntryStub is loaded from the IsolateRoot so that generated code is
// Isolate independent. At the moment this is only done for CEntryStub(1).
+ Node* isolate_root = BuildLoadIsolateRoot();
DCHECK_EQ(1, fun->result_size);
- Node* centry_stub = LOAD_INSTANCE_FIELD(
- CEntryStub, MachineType::TypeCompressedTaggedPointer());
+ auto centry_id =
+ Builtins::kCEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit;
+ Node* centry_stub = LOAD_TAGGED_POINTER(
+ isolate_root, IsolateData::builtin_slot_offset(centry_id));
// TODO(titzer): allow arbitrary number of runtime arguments
// At the moment we only allow 5 parameters. If more parameters are needed,
// increase this constant accordingly.
@@ -3943,30 +3946,43 @@ Graph* WasmGraphBuilder::graph() { return mcgraph()->graph(); }
namespace {
Signature<MachineRepresentation>* CreateMachineSignature(
- Zone* zone, wasm::FunctionSig* sig) {
+ Zone* zone, wasm::FunctionSig* sig, WasmGraphBuilder::CallOrigin origin) {
Signature<MachineRepresentation>::Builder builder(zone, sig->return_count(),
sig->parameter_count());
for (auto ret : sig->returns()) {
- builder.AddReturn(wasm::ValueTypes::MachineRepresentationFor(ret));
+ if (origin == WasmGraphBuilder::kCalledFromJS) {
+ builder.AddReturn(MachineRepresentation::kTagged);
+ } else {
+ builder.AddReturn(wasm::ValueTypes::MachineRepresentationFor(ret));
+ }
}
for (auto param : sig->parameters()) {
- builder.AddParam(wasm::ValueTypes::MachineRepresentationFor(param));
+ if (origin == WasmGraphBuilder::kCalledFromJS) {
+ // Parameters coming from JavaScript are always tagged values. Especially
+ // when the signature says that it's an I64 value, then a BigInt object is
+ // provided by JavaScript, and not two 32-bit parameters.
+ builder.AddParam(MachineRepresentation::kTagged);
+ } else {
+ builder.AddParam(wasm::ValueTypes::MachineRepresentationFor(param));
+ }
}
return builder.Build();
}
} // namespace
-void WasmGraphBuilder::LowerInt64() {
+void WasmGraphBuilder::LowerInt64(CallOrigin origin) {
if (mcgraph()->machine()->Is64()) return;
Int64Lowering r(mcgraph()->graph(), mcgraph()->machine(), mcgraph()->common(),
mcgraph()->zone(),
- CreateMachineSignature(mcgraph()->zone(), sig_));
+ CreateMachineSignature(mcgraph()->zone(), sig_, origin),
+ std::move(lowering_special_case_));
r.LowerGraph();
}
void WasmGraphBuilder::SimdScalarLoweringForTesting() {
- SimdScalarLowering(mcgraph(), CreateMachineSignature(mcgraph()->zone(), sig_))
+ SimdScalarLowering(mcgraph(), CreateMachineSignature(mcgraph()->zone(), sig_,
+ kCalledFromWasm))
.LowerGraph();
}
@@ -3992,6 +4008,24 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
return graph()->NewNode(mcgraph()->machine()->F64x2Abs(), inputs[0]);
case wasm::kExprF64x2Neg:
return graph()->NewNode(mcgraph()->machine()->F64x2Neg(), inputs[0]);
+ case wasm::kExprF64x2Add:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Add(), inputs[0],
+ inputs[1]);
+ case wasm::kExprF64x2Sub:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Sub(), inputs[0],
+ inputs[1]);
+ case wasm::kExprF64x2Mul:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Mul(), inputs[0],
+ inputs[1]);
+ case wasm::kExprF64x2Div:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Div(), inputs[0],
+ inputs[1]);
+ case wasm::kExprF64x2Min:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Min(), inputs[0],
+ inputs[1]);
+ case wasm::kExprF64x2Max:
+ return graph()->NewNode(mcgraph()->machine()->F64x2Max(), inputs[0],
+ inputs[1]);
case wasm::kExprF64x2Eq:
return graph()->NewNode(mcgraph()->machine()->F64x2Eq(), inputs[0],
inputs[1]);
@@ -4040,6 +4074,9 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
case wasm::kExprF32x4Mul:
return graph()->NewNode(mcgraph()->machine()->F32x4Mul(), inputs[0],
inputs[1]);
+ case wasm::kExprF32x4Div:
+ return graph()->NewNode(mcgraph()->machine()->F32x4Div(), inputs[0],
+ inputs[1]);
case wasm::kExprF32x4Min:
return graph()->NewNode(mcgraph()->machine()->F32x4Min(), inputs[0],
inputs[1]);
@@ -4068,6 +4105,12 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
return graph()->NewNode(mcgraph()->machine()->I64x2Splat(), inputs[0]);
case wasm::kExprI64x2Neg:
return graph()->NewNode(mcgraph()->machine()->I64x2Neg(), inputs[0]);
+ case wasm::kExprI64x2Shl:
+ return graph()->NewNode(mcgraph()->machine()->I64x2Shl(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI64x2ShrS:
+ return graph()->NewNode(mcgraph()->machine()->I64x2ShrS(), inputs[0],
+ inputs[1]);
case wasm::kExprI64x2Add:
return graph()->NewNode(mcgraph()->machine()->I64x2Add(), inputs[0],
inputs[1]);
@@ -4077,6 +4120,12 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
case wasm::kExprI64x2Mul:
return graph()->NewNode(mcgraph()->machine()->I64x2Mul(), inputs[0],
inputs[1]);
+ case wasm::kExprI64x2MinS:
+ return graph()->NewNode(mcgraph()->machine()->I64x2MinS(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI64x2MaxS:
+ return graph()->NewNode(mcgraph()->machine()->I64x2MaxS(), inputs[0],
+ inputs[1]);
case wasm::kExprI64x2Eq:
return graph()->NewNode(mcgraph()->machine()->I64x2Eq(), inputs[0],
inputs[1]);
@@ -4095,6 +4144,15 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
case wasm::kExprI64x2GeS:
return graph()->NewNode(mcgraph()->machine()->I64x2GeS(), inputs[0],
inputs[1]);
+ case wasm::kExprI64x2ShrU:
+ return graph()->NewNode(mcgraph()->machine()->I64x2ShrU(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI64x2MinU:
+ return graph()->NewNode(mcgraph()->machine()->I64x2MinU(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI64x2MaxU:
+ return graph()->NewNode(mcgraph()->machine()->I64x2MaxU(), inputs[0],
+ inputs[1]);
case wasm::kExprI64x2LtU:
return graph()->NewNode(mcgraph()->machine()->I64x2GtU(), inputs[1],
inputs[0]);
@@ -4123,6 +4181,12 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
inputs[0]);
case wasm::kExprI32x4Neg:
return graph()->NewNode(mcgraph()->machine()->I32x4Neg(), inputs[0]);
+ case wasm::kExprI32x4Shl:
+ return graph()->NewNode(mcgraph()->machine()->I32x4Shl(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI32x4ShrS:
+ return graph()->NewNode(mcgraph()->machine()->I32x4ShrS(), inputs[0],
+ inputs[1]);
case wasm::kExprI32x4Add:
return graph()->NewNode(mcgraph()->machine()->I32x4Add(), inputs[0],
inputs[1]);
@@ -4165,6 +4229,9 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
case wasm::kExprI32x4UConvertI16x8High:
return graph()->NewNode(mcgraph()->machine()->I32x4UConvertI16x8High(),
inputs[0]);
+ case wasm::kExprI32x4ShrU:
+ return graph()->NewNode(mcgraph()->machine()->I32x4ShrU(), inputs[0],
+ inputs[1]);
case wasm::kExprI32x4MinU:
return graph()->NewNode(mcgraph()->machine()->I32x4MinU(), inputs[0],
inputs[1]);
@@ -4191,6 +4258,12 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
case wasm::kExprI16x8SConvertI8x16High:
return graph()->NewNode(mcgraph()->machine()->I16x8SConvertI8x16High(),
inputs[0]);
+ case wasm::kExprI16x8Shl:
+ return graph()->NewNode(mcgraph()->machine()->I16x8Shl(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI16x8ShrS:
+ return graph()->NewNode(mcgraph()->machine()->I16x8ShrS(), inputs[0],
+ inputs[1]);
case wasm::kExprI16x8Neg:
return graph()->NewNode(mcgraph()->machine()->I16x8Neg(), inputs[0]);
case wasm::kExprI16x8SConvertI32x4:
@@ -4247,6 +4320,9 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
case wasm::kExprI16x8UConvertI32x4:
return graph()->NewNode(mcgraph()->machine()->I16x8UConvertI32x4(),
inputs[0], inputs[1]);
+ case wasm::kExprI16x8ShrU:
+ return graph()->NewNode(mcgraph()->machine()->I16x8ShrU(), inputs[0],
+ inputs[1]);
case wasm::kExprI16x8AddSaturateU:
return graph()->NewNode(mcgraph()->machine()->I16x8AddSaturateU(),
inputs[0], inputs[1]);
@@ -4275,6 +4351,12 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
return graph()->NewNode(mcgraph()->machine()->I8x16Splat(), inputs[0]);
case wasm::kExprI8x16Neg:
return graph()->NewNode(mcgraph()->machine()->I8x16Neg(), inputs[0]);
+ case wasm::kExprI8x16Shl:
+ return graph()->NewNode(mcgraph()->machine()->I8x16Shl(), inputs[0],
+ inputs[1]);
+ case wasm::kExprI8x16ShrS:
+ return graph()->NewNode(mcgraph()->machine()->I8x16ShrS(), inputs[0],
+ inputs[1]);
case wasm::kExprI8x16SConvertI16x8:
return graph()->NewNode(mcgraph()->machine()->I8x16SConvertI16x8(),
inputs[0], inputs[1]);
@@ -4317,6 +4399,9 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
case wasm::kExprI8x16GeS:
return graph()->NewNode(mcgraph()->machine()->I8x16GeS(), inputs[0],
inputs[1]);
+ case wasm::kExprI8x16ShrU:
+ return graph()->NewNode(mcgraph()->machine()->I8x16ShrU(), inputs[0],
+ inputs[1]);
case wasm::kExprI8x16UConvertI16x8:
return graph()->NewNode(mcgraph()->machine()->I8x16UConvertI16x8(),
inputs[0], inputs[1]);
@@ -4424,47 +4509,6 @@ Node* WasmGraphBuilder::SimdLaneOp(wasm::WasmOpcode opcode, uint8_t lane,
}
}
-Node* WasmGraphBuilder::SimdShiftOp(wasm::WasmOpcode opcode, uint8_t shift,
- Node* const* inputs) {
- has_simd_ = true;
- switch (opcode) {
- case wasm::kExprI64x2Shl:
- return graph()->NewNode(mcgraph()->machine()->I64x2Shl(shift), inputs[0]);
- case wasm::kExprI64x2ShrS:
- return graph()->NewNode(mcgraph()->machine()->I64x2ShrS(shift),
- inputs[0]);
- case wasm::kExprI64x2ShrU:
- return graph()->NewNode(mcgraph()->machine()->I64x2ShrU(shift),
- inputs[0]);
- case wasm::kExprI32x4Shl:
- return graph()->NewNode(mcgraph()->machine()->I32x4Shl(shift), inputs[0]);
- case wasm::kExprI32x4ShrS:
- return graph()->NewNode(mcgraph()->machine()->I32x4ShrS(shift),
- inputs[0]);
- case wasm::kExprI32x4ShrU:
- return graph()->NewNode(mcgraph()->machine()->I32x4ShrU(shift),
- inputs[0]);
- case wasm::kExprI16x8Shl:
- return graph()->NewNode(mcgraph()->machine()->I16x8Shl(shift), inputs[0]);
- case wasm::kExprI16x8ShrS:
- return graph()->NewNode(mcgraph()->machine()->I16x8ShrS(shift),
- inputs[0]);
- case wasm::kExprI16x8ShrU:
- return graph()->NewNode(mcgraph()->machine()->I16x8ShrU(shift),
- inputs[0]);
- case wasm::kExprI8x16Shl:
- return graph()->NewNode(mcgraph()->machine()->I8x16Shl(shift), inputs[0]);
- case wasm::kExprI8x16ShrS:
- return graph()->NewNode(mcgraph()->machine()->I8x16ShrS(shift),
- inputs[0]);
- case wasm::kExprI8x16ShrU:
- return graph()->NewNode(mcgraph()->machine()->I8x16ShrU(shift),
- inputs[0]);
- default:
- FATAL_UNSUPPORTED_OPCODE(opcode);
- }
-}
-
Node* WasmGraphBuilder::Simd8x16ShuffleOp(const uint8_t shuffle[16],
Node* const* inputs) {
has_simd_ = true;
@@ -5010,15 +5054,86 @@ void WasmGraphBuilder::RemoveBytecodePositionDecorator() {
namespace {
class WasmWrapperGraphBuilder : public WasmGraphBuilder {
public:
- WasmWrapperGraphBuilder(Zone* zone, JSGraph* jsgraph, wasm::FunctionSig* sig,
+ WasmWrapperGraphBuilder(Zone* zone, MachineGraph* mcgraph,
+ wasm::FunctionSig* sig,
compiler::SourcePositionTable* spt,
StubCallMode stub_mode, wasm::WasmFeatures features)
- : WasmGraphBuilder(nullptr, zone, jsgraph, sig, spt),
- isolate_(jsgraph->isolate()),
- jsgraph_(jsgraph),
+ : WasmGraphBuilder(nullptr, zone, mcgraph, sig, spt),
stub_mode_(stub_mode),
enabled_features_(features) {}
+ CallDescriptor* GetI32PairToBigIntCallDescriptor() {
+ I32PairToBigIntDescriptor interface_descriptor;
+
+ return Linkage::GetStubCallDescriptor(
+ mcgraph()->zone(), // zone
+ interface_descriptor, // descriptor
+ interface_descriptor.GetStackParameterCount(), // stack parameter count
+ CallDescriptor::kNoFlags, // flags
+ Operator::kNoProperties, // properties
+ stub_mode_); // stub call mode
+ }
+
+ CallDescriptor* GetI64ToBigIntCallDescriptor() {
+ if (!lowering_special_case_) {
+ lowering_special_case_ = base::make_unique<Int64LoweringSpecialCase>();
+ }
+
+ if (lowering_special_case_->i64_to_bigint_call_descriptor) {
+ return lowering_special_case_->i64_to_bigint_call_descriptor;
+ }
+
+ I64ToBigIntDescriptor interface_descriptor;
+ auto call_descriptor = Linkage::GetStubCallDescriptor(
+ mcgraph()->zone(), // zone
+ interface_descriptor, // descriptor
+ interface_descriptor.GetStackParameterCount(), // stack parameter count
+ CallDescriptor::kNoFlags, // flags
+ Operator::kNoProperties, // properties
+ stub_mode_); // stub call mode
+
+ lowering_special_case_->i64_to_bigint_call_descriptor = call_descriptor;
+ lowering_special_case_->i32_pair_to_bigint_call_descriptor =
+ GetI32PairToBigIntCallDescriptor();
+ return call_descriptor;
+ }
+
+ CallDescriptor* GetBigIntToI32PairCallDescriptor() {
+ BigIntToI32PairDescriptor interface_descriptor;
+
+ return Linkage::GetStubCallDescriptor(
+ mcgraph()->zone(), // zone
+ interface_descriptor, // descriptor
+ interface_descriptor.GetStackParameterCount(), // stack parameter count
+ CallDescriptor::kNoFlags, // flags
+ Operator::kNoProperties, // properties
+ stub_mode_); // stub call mode
+ }
+
+ CallDescriptor* GetBigIntToI64CallDescriptor() {
+ if (!lowering_special_case_) {
+ lowering_special_case_ = base::make_unique<Int64LoweringSpecialCase>();
+ }
+
+ if (lowering_special_case_->bigint_to_i64_call_descriptor) {
+ return lowering_special_case_->bigint_to_i64_call_descriptor;
+ }
+
+ BigIntToI64Descriptor interface_descriptor;
+ auto call_descriptor = Linkage::GetStubCallDescriptor(
+ mcgraph()->zone(), // zone
+ interface_descriptor, // descriptor
+ interface_descriptor.GetStackParameterCount(), // stack parameter count
+ CallDescriptor::kNoFlags, // flags
+ Operator::kNoProperties, // properties
+ stub_mode_); // stub call mode
+
+ lowering_special_case_->bigint_to_i64_call_descriptor = call_descriptor;
+ lowering_special_case_->bigint_to_i32_pair_call_descriptor =
+ GetBigIntToI32PairCallDescriptor();
+ return call_descriptor;
+ }
+
Node* BuildAllocateHeapNumberWithValue(Node* value, Node* control) {
MachineOperatorBuilder* machine = mcgraph()->machine();
CommonOperatorBuilder* common = mcgraph()->common();
@@ -5027,7 +5142,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
? mcgraph()->RelocatableIntPtrConstant(
wasm::WasmCode::kWasmAllocateHeapNumber,
RelocInfo::WASM_STUB_CALL)
- : BuildLoadBuiltinFromInstance(Builtins::kAllocateHeapNumber);
+ : BuildLoadBuiltinFromIsolateRoot(Builtins::kAllocateHeapNumber);
if (!allocate_heap_number_operator_.is_set()) {
auto call_descriptor = Linkage::GetStubCallDescriptor(
mcgraph()->zone(), AllocateHeapNumberDescriptor(), 0,
@@ -5084,10 +5199,9 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
return undefined_value_node_.get();
}
- Node* BuildLoadBuiltinFromInstance(int builtin_index) {
+ Node* BuildLoadBuiltinFromIsolateRoot(int builtin_index) {
DCHECK(Builtins::IsBuiltinId(builtin_index));
- Node* isolate_root =
- LOAD_INSTANCE_FIELD(IsolateRoot, MachineType::Pointer());
+ Node* isolate_root = BuildLoadIsolateRoot();
return LOAD_TAGGED_POINTER(isolate_root,
IsolateData::builtin_slot_offset(builtin_index));
}
@@ -5213,7 +5327,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
vsmi, vbox, merge);
}
- int AddArgumentNodes(Node** args, int pos, int param_count,
+ int AddArgumentNodes(Vector<Node*> args, int pos, int param_count,
wasm::FunctionSig* sig) {
// Convert wasm numbers to JS values.
for (int i = 0; i < param_count; ++i) {
@@ -5232,7 +5346,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
(stub_mode_ == StubCallMode::kCallWasmRuntimeStub)
? mcgraph()->RelocatableIntPtrConstant(
wasm::WasmCode::kWasmToNumber, RelocInfo::WASM_STUB_CALL)
- : BuildLoadBuiltinFromInstance(Builtins::kToNumber);
+ : BuildLoadBuiltinFromIsolateRoot(Builtins::kToNumber);
Node* result = SetEffect(
graph()->NewNode(mcgraph()->common()->Call(call_descriptor), stub_code,
@@ -5317,47 +5431,59 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
}
Node* BuildChangeInt64ToBigInt(Node* input) {
- I64ToBigIntDescriptor interface_descriptor;
-
- auto call_descriptor = Linkage::GetStubCallDescriptor(
- mcgraph()->zone(), // zone
- interface_descriptor, // descriptor
- interface_descriptor.GetStackParameterCount(), // stack parameter count
- CallDescriptor::kNoFlags, // flags
- Operator::kNoProperties, // properties
- stub_mode_); // stub call mode
-
- Node* target =
- (stub_mode_ == StubCallMode::kCallWasmRuntimeStub)
- ? mcgraph()->RelocatableIntPtrConstant(
- wasm::WasmCode::kWasmI64ToBigInt, RelocInfo::WASM_STUB_CALL)
- : BuildLoadBuiltinFromInstance(Builtins::kI64ToBigInt);
+ const Operator* call =
+ mcgraph()->common()->Call(GetI64ToBigIntCallDescriptor());
+
+ Node* target;
+ if (mcgraph()->machine()->Is64()) {
+ target =
+ (stub_mode_ == StubCallMode::kCallWasmRuntimeStub)
+ ? mcgraph()->RelocatableIntPtrConstant(
+ wasm::WasmCode::kWasmI64ToBigInt, RelocInfo::WASM_STUB_CALL)
+ : BuildLoadBuiltinFromIsolateRoot(Builtins::kI64ToBigInt);
+ } else {
+ DCHECK(mcgraph()->machine()->Is32());
+ // On 32-bit platforms we already set the target to the
+ // I32PairToBigInt builtin here, so that we don't have to replace the
+ // target in the int64-lowering.
+ target =
+ (stub_mode_ == StubCallMode::kCallWasmRuntimeStub)
+ ? mcgraph()->RelocatableIntPtrConstant(
+ wasm::WasmCode::kWasmI32PairToBigInt,
+ RelocInfo::WASM_STUB_CALL)
+ : BuildLoadBuiltinFromIsolateRoot(Builtins::kI32PairToBigInt);
+ }
return SetEffect(
- SetControl(graph()->NewNode(mcgraph()->common()->Call(call_descriptor),
- target, input, Effect(), Control())));
+ SetControl(graph()->NewNode(call, target, input, Effect(), Control())));
}
Node* BuildChangeBigIntToInt64(Node* input, Node* context) {
- BigIntToI64Descriptor interface_descriptor;
-
- auto call_descriptor = Linkage::GetStubCallDescriptor(
- mcgraph()->zone(), // zone
- interface_descriptor, // descriptor
- interface_descriptor.GetStackParameterCount(), // stack parameter count
- CallDescriptor::kNoFlags, // flags
- Operator::kNoProperties, // properties
- stub_mode_); // stub call mode
-
- Node* target =
- (stub_mode_ == StubCallMode::kCallWasmRuntimeStub)
- ? mcgraph()->RelocatableIntPtrConstant(
- wasm::WasmCode::kWasmBigIntToI64, RelocInfo::WASM_STUB_CALL)
- : BuildLoadBuiltinFromInstance(Builtins::kBigIntToI64);
+ const Operator* call =
+ mcgraph()->common()->Call(GetBigIntToI64CallDescriptor());
+
+ Node* target;
+ if (mcgraph()->machine()->Is64()) {
+ target =
+ (stub_mode_ == StubCallMode::kCallWasmRuntimeStub)
+ ? mcgraph()->RelocatableIntPtrConstant(
+ wasm::WasmCode::kWasmBigIntToI64, RelocInfo::WASM_STUB_CALL)
+ : BuildLoadBuiltinFromIsolateRoot(Builtins::kBigIntToI64);
+ } else {
+ DCHECK(mcgraph()->machine()->Is32());
+ // On 32-bit platforms we already set the target to the
+ // BigIntToI32Pair builtin here, so that we don't have to replace the
+ // target in the int64-lowering.
+ target =
+ (stub_mode_ == StubCallMode::kCallWasmRuntimeStub)
+ ? mcgraph()->RelocatableIntPtrConstant(
+ wasm::WasmCode::kWasmBigIntToI32Pair,
+ RelocInfo::WASM_STUB_CALL)
+ : BuildLoadBuiltinFromIsolateRoot(Builtins::kBigIntToI32Pair);
+ }
return SetEffect(SetControl(
- graph()->NewNode(mcgraph()->common()->Call(call_descriptor), target,
- input, context, Effect(), Control())));
+ graph()->NewNode(call, target, input, context, Effect(), Control())));
}
Node* FromJS(Node* node, Node* js_context, wasm::ValueType type) {
@@ -5427,8 +5553,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
void BuildModifyThreadInWasmFlag(bool new_value) {
if (!trap_handler::IsTrapHandlerEnabled()) return;
- Node* isolate_root =
- LOAD_INSTANCE_FIELD(IsolateRoot, MachineType::Pointer());
+ Node* isolate_root = BuildLoadIsolateRoot();
Node* thread_in_wasm_flag_address =
LOAD_RAW(isolate_root, Isolate::thread_in_wasm_flag_address_offset(),
@@ -5446,9 +5571,10 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Diamond flag_check(graph(), mcgraph()->common(), check,
BranchHint::kTrue);
flag_check.Chain(Control());
- Node* message_id = jsgraph()->SmiConstant(static_cast<int32_t>(
- new_value ? AbortReason::kUnexpectedThreadInWasmSet
- : AbortReason::kUnexpectedThreadInWasmUnset));
+ Node* message_id = graph()->NewNode(
+ mcgraph()->common()->NumberConstant(static_cast<int32_t>(
+ new_value ? AbortReason::kUnexpectedThreadInWasmSet
+ : AbortReason::kUnexpectedThreadInWasmUnset)));
Node* effect = Effect();
BuildCallToRuntimeWithContext(Runtime::kAbort, NoContextConstant(),
@@ -5509,7 +5635,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
// Create the js_closure and js_context parameters.
Node* js_closure =
- graph()->NewNode(jsgraph()->common()->Parameter(
+ graph()->NewNode(mcgraph()->common()->Parameter(
Linkage::kJSCallClosureParamIndex, "%closure"),
graph()->start());
Node* js_context = graph()->NewNode(
@@ -5525,18 +5651,18 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
instance_node_.set(
BuildLoadInstanceFromExportedFunctionData(function_data));
- if (!wasm::IsJSCompatibleSignature(sig_, enabled_features_.bigint)) {
+ if (!wasm::IsJSCompatibleSignature(sig_, enabled_features_)) {
// Throw a TypeError. Use the js_context of the calling javascript
// function (passed as a parameter), such that the generated code is
// js_context independent.
BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, js_context,
nullptr, 0, effect_, Control());
- Return(jsgraph()->SmiConstant(0));
+ TerminateThrow(Effect(), Control());
return;
}
const int args_count = wasm_count + 1; // +1 for wasm_code.
- Node** args = Buffer(args_count);
+ Vector<Node*> args = Buffer(args_count);
Node** rets;
// Convert JS parameters to wasm numbers.
@@ -5554,8 +5680,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
// Load function index from {WasmExportedFunctionData}.
Node* function_index =
BuildLoadFunctionIndexFromExportedFunctionData(function_data);
- BuildImportCall(sig_, args, &rets, wasm::kNoCodePosition, function_index,
- kCallContinues);
+ BuildImportCall(sig_, args.begin(), &rets, wasm::kNoCodePosition,
+ function_index, kCallContinues);
} else {
// Call to a wasm function defined in this module.
// The call target is the jump table slot for that function.
@@ -5567,16 +5693,35 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
mcgraph()->machine()->IntAdd(), jump_table_start, jump_table_offset);
args[0] = jump_table_slot;
- BuildWasmCall(sig_, args, &rets, wasm::kNoCodePosition, nullptr,
+ BuildWasmCall(sig_, args.begin(), &rets, wasm::kNoCodePosition, nullptr,
kNoRetpoline);
}
// Clear the ThreadInWasm flag.
BuildModifyThreadInWasmFlag(false);
- Node* jsval = sig_->return_count() == 0 ? jsgraph()->UndefinedConstant()
- : ToJS(rets[0], sig_->GetReturn());
+ Node* jsval;
+ if (sig_->return_count() == 0) {
+ jsval = BuildLoadUndefinedValueFromInstance();
+ } else if (sig_->return_count() == 1) {
+ jsval = ToJS(rets[0], sig_->GetReturn());
+ } else {
+ int32_t return_count = static_cast<int32_t>(sig_->return_count());
+ Node* size =
+ graph()->NewNode(mcgraph()->common()->NumberConstant(return_count));
+ // TODO(thibaudm): Replace runtime calls with TurboFan code.
+ Node* fixed_array =
+ BuildCallToRuntime(Runtime::kWasmNewMultiReturnFixedArray, &size, 1);
+ for (int i = 0; i < return_count; ++i) {
+ Node* value = ToJS(rets[i], sig_->GetReturn(i));
+ STORE_FIXED_ARRAY_SLOT_ANY(fixed_array, i, value);
+ }
+ jsval = BuildCallToRuntimeWithContext(Runtime::kWasmNewMultiReturnJSArray,
+ js_context, &fixed_array, 1,
+ effect_, Control());
+ }
Return(jsval);
+ if (ContainsInt64(sig_)) LowerInt64(kCalledFromJS);
}
bool BuildWasmImportCallWrapper(WasmImportCallKind kind) {
@@ -5597,9 +5742,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError,
native_context, nullptr, 0, effect_,
Control());
- // We don't need to return a value here, as the runtime call will not
- // return anyway (the c entry stub will trigger stack unwinding).
- ReturnVoid();
+ TerminateThrow(Effect(), Control());
return false;
}
@@ -5622,7 +5765,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
sloppy_receiver = false;
V8_FALLTHROUGH; // fallthru
case WasmImportCallKind::kJSFunctionArityMatchSloppy: {
- Node** args = Buffer(wasm_count + 9);
+ Vector<Node*> args = Buffer(wasm_count + 7);
int pos = 0;
Node* function_context =
LOAD_RAW(callable_node,
@@ -5650,8 +5793,9 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
args[pos++] = Effect();
args[pos++] = Control();
+ DCHECK_EQ(pos, args.size());
call = graph()->NewNode(mcgraph()->common()->Call(call_descriptor), pos,
- args);
+ args.begin());
break;
}
// =======================================================================
@@ -5661,14 +5805,14 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
sloppy_receiver = false;
V8_FALLTHROUGH; // fallthru
case WasmImportCallKind::kJSFunctionArityMismatchSloppy: {
- Node** args = Buffer(wasm_count + 9);
+ Vector<Node*> args = Buffer(wasm_count + 9);
int pos = 0;
Node* function_context =
LOAD_RAW(callable_node,
wasm::ObjectAccess::ContextOffsetInTaggedJSFunction(),
MachineType::TypeCompressedTaggedPointer());
- args[pos++] =
- BuildLoadBuiltinFromInstance(Builtins::kArgumentsAdaptorTrampoline);
+ args[pos++] = BuildLoadBuiltinFromIsolateRoot(
+ Builtins::kArgumentsAdaptorTrampoline);
args[pos++] = callable_node; // target callable
args[pos++] = undefined_node; // new target
args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count
@@ -5712,26 +5856,27 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
args[pos++] = function_context;
args[pos++] = Effect();
args[pos++] = Control();
+
+ DCHECK_EQ(pos, args.size());
call = graph()->NewNode(mcgraph()->common()->Call(call_descriptor), pos,
- args);
+ args.begin());
break;
}
// =======================================================================
// === General case of unknown callable ==================================
// =======================================================================
case WasmImportCallKind::kUseCallBuiltin: {
- Node** args = Buffer(wasm_count + 9);
+ Vector<Node*> args = Buffer(wasm_count + 7);
int pos = 0;
- args[pos++] = mcgraph()->RelocatableIntPtrConstant(
- wasm::WasmCode::kWasmCallJavaScript, RelocInfo::WASM_STUB_CALL);
+ args[pos++] =
+ BuildLoadBuiltinFromIsolateRoot(Builtins::kCall_ReceiverIsAny);
args[pos++] = callable_node;
args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count
args[pos++] = undefined_node; // receiver
auto call_descriptor = Linkage::GetStubCallDescriptor(
graph()->zone(), CallTrampolineDescriptor{}, wasm_count + 1,
- CallDescriptor::kNoFlags, Operator::kNoProperties,
- StubCallMode::kCallWasmRuntimeStub);
+ CallDescriptor::kNoFlags, Operator::kNoProperties);
// Convert wasm numbers to JS values.
pos = AddArgumentNodes(args, pos, wasm_count, sig_);
@@ -5745,8 +5890,9 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
args[pos++] = Effect();
args[pos++] = Control();
+ DCHECK_EQ(pos, args.size());
call = graph()->NewNode(mcgraph()->common()->Call(call_descriptor), pos,
- args);
+ args.begin());
break;
}
default:
@@ -5766,6 +5912,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
BuildModifyThreadInWasmFlag(true);
Return(val);
+
+ if (ContainsInt64(sig_)) LowerInt64(kCalledFromWasm);
return true;
}
@@ -5807,13 +5955,12 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Node* sfi_data = LOAD_RAW(
shared, SharedFunctionInfo::kFunctionDataOffset - kHeapObjectTag,
MachineType::TypeCompressedTagged());
- Node* host_data = LOAD_RAW(
+ Node* host_data_foreign = LOAD_RAW(
sfi_data, WasmCapiFunctionData::kEmbedderDataOffset - kHeapObjectTag,
- MachineType::Pointer());
+ MachineType::TypeCompressedTagged());
BuildModifyThreadInWasmFlag(false);
- Node* isolate_root =
- LOAD_INSTANCE_FIELD(IsolateRoot, MachineType::Pointer());
+ Node* isolate_root = BuildLoadIsolateRoot();
Node* fp_value = graph()->NewNode(mcgraph()->machine()->LoadFramePointer());
STORE_RAW(isolate_root, Isolate::c_entry_fp_offset(), fp_value,
MachineType::PointerRepresentation(), kNoWriteBarrier);
@@ -5824,11 +5971,12 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Node* function =
graph()->NewNode(mcgraph()->common()->ExternalConstant(ref));
- // Parameters: void* data, Address arguments.
+ // Parameters: Address host_data_foreign, Address arguments.
MachineType host_sig_types[] = {
MachineType::Pointer(), MachineType::Pointer(), MachineType::Pointer()};
MachineSignature host_sig(1, 2, host_sig_types);
- Node* return_value = BuildCCall(&host_sig, function, host_data, values);
+ Node* return_value =
+ BuildCCall(&host_sig, function, host_data_foreign, values);
BuildModifyThreadInWasmFlag(true);
@@ -5854,13 +6002,13 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
SetControl(
graph()->NewNode(mcgraph()->common()->IfTrue(), exception_branch));
DCHECK_LT(sig_->return_count(), wasm::kV8MaxWasmFunctionMultiReturns);
- int return_count = static_cast<int>(sig_->return_count());
+ size_t return_count = sig_->return_count();
if (return_count == 0) {
Return(Int32Constant(0));
} else {
- Node** returns = Buffer(return_count);
+ Vector<Node*> returns = Buffer(return_count);
offset = 0;
- for (int i = 0; i < return_count; ++i) {
+ for (size_t i = 0; i < return_count; ++i) {
wasm::ValueType type = sig_->GetReturn(i);
Node* val = SetEffect(
graph()->NewNode(GetSafeLoadOperator(offset, type), values,
@@ -5868,10 +6016,10 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
returns[i] = val;
offset += wasm::ValueTypes::ElementSizeInBytes(type);
}
- Return(return_count, returns);
+ Return(returns);
}
- if (ContainsInt64(sig_)) LowerInt64();
+ if (ContainsInt64(sig_)) LowerInt64(kCalledFromWasm);
}
void BuildWasmInterpreterEntry(int func_index) {
@@ -5918,17 +6066,19 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
// We are passing the raw arg_buffer here. To the GC and other parts, it
// looks like a Smi (lowest bit not set). In the runtime function however,
// don't call Smi::value on it, but just cast it to a byte pointer.
- Node* parameters[] = {jsgraph()->SmiConstant(func_index), arg_buffer};
+ Node* parameters[] = {
+ graph()->NewNode(mcgraph()->common()->NumberConstant(func_index)),
+ arg_buffer};
BuildCallToRuntime(Runtime::kWasmRunInterpreter, parameters,
arraysize(parameters));
// Read back the return value.
DCHECK_LT(sig_->return_count(), wasm::kV8MaxWasmFunctionMultiReturns);
- unsigned return_count = static_cast<unsigned>(sig_->return_count());
+ size_t return_count = sig_->return_count();
if (return_count == 0) {
Return(Int32Constant(0));
} else {
- Node** returns = Buffer(return_count);
+ Vector<Node*> returns = Buffer(return_count);
offset = 0;
for (size_t i = 0; i < return_count; ++i) {
wasm::ValueType type = sig_->GetReturn(i);
@@ -5938,10 +6088,85 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
returns[i] = val;
offset += wasm::ValueTypes::ElementSizeInBytes(type);
}
- Return(return_count, returns);
+ Return(returns);
}
- if (ContainsInt64(sig_)) LowerInt64();
+ if (ContainsInt64(sig_)) LowerInt64(kCalledFromWasm);
+ }
+
+ void BuildJSToJSWrapper(Isolate* isolate) {
+ int wasm_count = static_cast<int>(sig_->parameter_count());
+
+ // Build the start and the parameter nodes.
+ int param_count = 1 /* closure */ + 1 /* receiver */ + wasm_count +
+ 1 /* new.target */ + 1 /* #arg */ + 1 /* context */;
+ SetEffect(SetControl(Start(param_count)));
+ Node* closure = Param(Linkage::kJSCallClosureParamIndex);
+ Node* context = Param(Linkage::GetJSCallContextParamIndex(wasm_count + 1));
+
+ // Since JS-to-JS wrappers are specific to one Isolate, it is OK to embed
+ // values (for undefined and root) directly into the instruction stream.
+ isolate_root_node_ = mcgraph()->IntPtrConstant(isolate->isolate_root());
+ undefined_value_node_ = graph()->NewNode(mcgraph()->common()->HeapConstant(
+ isolate->factory()->undefined_value()));
+
+ // Throw a TypeError if the signature is incompatible with JavaScript.
+ if (!wasm::IsJSCompatibleSignature(sig_, enabled_features_)) {
+ BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, context,
+ nullptr, 0, effect_, Control());
+ TerminateThrow(Effect(), Control());
+ return;
+ }
+
+ // Load the original callable from the closure.
+ Node* shared = LOAD_TAGGED_ANY(
+ closure,
+ wasm::ObjectAccess::ToTagged(JSFunction::kSharedFunctionInfoOffset));
+ Node* func_data = LOAD_TAGGED_ANY(
+ shared,
+ wasm::ObjectAccess::ToTagged(SharedFunctionInfo::kFunctionDataOffset));
+ Node* callable = LOAD_TAGGED_ANY(
+ func_data,
+ wasm::ObjectAccess::ToTagged(WasmJSFunctionData::kCallableOffset));
+
+ // Call the underlying closure.
+ Vector<Node*> args = Buffer(wasm_count + 7);
+ int pos = 0;
+ args[pos++] = graph()->NewNode(mcgraph()->common()->HeapConstant(
+ BUILTIN_CODE(isolate, Call_ReceiverIsAny)));
+ args[pos++] = callable;
+ args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count
+ args[pos++] = BuildLoadUndefinedValueFromInstance(); // receiver
+
+ auto call_descriptor = Linkage::GetStubCallDescriptor(
+ graph()->zone(), CallTrampolineDescriptor{}, wasm_count + 1,
+ CallDescriptor::kNoFlags, Operator::kNoProperties,
+ StubCallMode::kCallCodeObject);
+
+ // Convert parameter JS values to wasm numbers and back to JS values.
+ for (int i = 0; i < wasm_count; ++i) {
+ Node* param = Param(i + 1); // Start from index 1 to skip receiver.
+ args[pos++] =
+ ToJS(FromJS(param, context, sig_->GetParam(i)), sig_->GetParam(i));
+ }
+
+ args[pos++] = context;
+ args[pos++] = Effect();
+ args[pos++] = Control();
+
+ DCHECK_EQ(pos, args.size());
+ Node* call = SetEffect(graph()->NewNode(
+ mcgraph()->common()->Call(call_descriptor), pos, args.begin()));
+
+ // TODO(wasm): Extend this to support multi-return.
+ DCHECK_LE(sig_->return_count(), 1);
+
+ // Convert return JS values to wasm numbers and back to JS values.
+ Node* jsval =
+ sig_->return_count() == 0
+ ? BuildLoadUndefinedValueFromInstance()
+ : ToJS(FromJS(call, context, sig_->GetReturn()), sig_->GetReturn());
+ Return(jsval);
}
void BuildCWasmEntry() {
@@ -5959,8 +6184,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
kNoWriteBarrier);
int wasm_arg_count = static_cast<int>(sig_->parameter_count());
- int arg_count = wasm_arg_count + 4; // code, object_ref, control, effect
- Node** args = Buffer(arg_count);
+ Vector<Node*> args = Buffer(wasm_arg_count + 4);
int pos = 0;
args[pos++] = code_entry;
@@ -5977,13 +6201,13 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
args[pos++] = Effect();
args[pos++] = Control();
- DCHECK_EQ(arg_count, pos);
// Call the wasm code.
auto call_descriptor = GetWasmCallDescriptor(mcgraph()->zone(), sig_);
+ DCHECK_EQ(pos, args.size());
Node* call = SetEffect(graph()->NewNode(
- mcgraph()->common()->Call(call_descriptor), arg_count, args));
+ mcgraph()->common()->Call(call_descriptor), pos, args.begin()));
Node* if_success = graph()->NewNode(mcgraph()->common()->IfSuccess(), call);
Node* if_exception =
@@ -6011,9 +6235,12 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
pos++;
}
- Return(jsgraph()->SmiConstant(0));
+ Return(mcgraph()->IntPtrConstant(0));
if (mcgraph()->machine()->Is32() && ContainsInt64(sig_)) {
+ // No special lowering should be requested in the C entry.
+ DCHECK_NULL(lowering_special_case_);
+
MachineRepresentation sig_reps[] = {
MachineType::PointerRepresentation(), // return value
MachineType::PointerRepresentation(), // target
@@ -6028,11 +6255,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
}
}
- JSGraph* jsgraph() { return jsgraph_; }
-
private:
- Isolate* const isolate_;
- JSGraph* jsgraph_;
StubCallMode stub_mode_;
SetOncePointer<Node> undefined_value_node_;
SetOncePointer<const Operator> allocate_heap_number_operator_;
@@ -6058,26 +6281,27 @@ void AppendSignature(char* buffer, size_t max_name_len,
} // namespace
std::unique_ptr<OptimizedCompilationJob> NewJSToWasmCompilationJob(
- Isolate* isolate, wasm::FunctionSig* sig, bool is_import) {
+ Isolate* isolate, wasm::WasmEngine* wasm_engine, wasm::FunctionSig* sig,
+ bool is_import, const wasm::WasmFeatures& enabled_features) {
//----------------------------------------------------------------------------
// Create the Graph.
//----------------------------------------------------------------------------
std::unique_ptr<Zone> zone =
- base::make_unique<Zone>(isolate->allocator(), ZONE_NAME);
+ base::make_unique<Zone>(wasm_engine->allocator(), ZONE_NAME);
Graph* graph = new (zone.get()) Graph(zone.get());
CommonOperatorBuilder common(zone.get());
MachineOperatorBuilder machine(
zone.get(), MachineType::PointerRepresentation(),
InstructionSelector::SupportedMachineOperatorFlags(),
InstructionSelector::AlignmentRequirements());
- JSGraph jsgraph(isolate, graph, &common, nullptr, nullptr, &machine);
+ MachineGraph mcgraph(graph, &common, &machine);
Node* control = nullptr;
Node* effect = nullptr;
- WasmWrapperGraphBuilder builder(zone.get(), &jsgraph, sig, nullptr,
+ WasmWrapperGraphBuilder builder(zone.get(), &mcgraph, sig, nullptr,
StubCallMode::kCallCodeObject,
- wasm::WasmFeaturesFromIsolate(isolate));
+ enabled_features);
builder.set_control_ptr(&control);
builder.set_effect_ptr(&effect);
builder.BuildJSToWasmWrapper(is_import);
@@ -6095,13 +6319,13 @@ std::unique_ptr<OptimizedCompilationJob> NewJSToWasmCompilationJob(
zone.get(), false, params + 1, CallDescriptor::kNoFlags);
return Pipeline::NewWasmHeapStubCompilationJob(
- isolate, incoming, std::move(zone), graph, Code::JS_TO_WASM_FUNCTION,
- std::move(debug_name), WasmAssemblerOptions());
+ isolate, wasm_engine, incoming, std::move(zone), graph,
+ Code::JS_TO_WASM_FUNCTION, std::move(debug_name), WasmAssemblerOptions());
}
std::pair<WasmImportCallKind, Handle<JSReceiver>> ResolveWasmImportCall(
Handle<JSReceiver> callable, wasm::FunctionSig* expected_sig,
- bool has_bigint_feature) {
+ const wasm::WasmFeatures& enabled_features) {
if (WasmExportedFunction::IsWasmExportedFunction(*callable)) {
auto imported_function = Handle<WasmExportedFunction>::cast(callable);
auto func_index = imported_function->function_index();
@@ -6136,7 +6360,7 @@ std::pair<WasmImportCallKind, Handle<JSReceiver>> ResolveWasmImportCall(
return std::make_pair(WasmImportCallKind::kWasmToCapi, callable);
}
// Assuming we are calling to JS, check whether this would be a runtime error.
- if (!wasm::IsJSCompatibleSignature(expected_sig, has_bigint_feature)) {
+ if (!wasm::IsJSCompatibleSignature(expected_sig, enabled_features)) {
return std::make_pair(WasmImportCallKind::kRuntimeTypeError, callable);
}
// For JavaScript calls, determine whether the target has an arity match
@@ -6176,10 +6400,7 @@ std::pair<WasmImportCallKind, Handle<JSReceiver>> ResolveWasmImportCall(
COMPARE_SIG_FOR_BUILTIN_F64(Exp);
COMPARE_SIG_FOR_BUILTIN_F64(Log);
COMPARE_SIG_FOR_BUILTIN_F64(Atan2);
- //===========================================================
- // TODO(8505): Math.pow for wasm does not match JS.
- // COMPARE_SIG_FOR_BUILTIN_F64(Pow);
- //===========================================================
+ COMPARE_SIG_FOR_BUILTIN_F64(Pow);
COMPARE_SIG_FOR_BUILTIN_F32_F64(Min);
COMPARE_SIG_FOR_BUILTIN_F32_F64(Max);
COMPARE_SIG_FOR_BUILTIN_F32_F64(Abs);
@@ -6347,7 +6568,7 @@ wasm::WasmCompilationResult CompileWasmImportCallWrapper(
&zone, MachineType::PointerRepresentation(),
InstructionSelector::SupportedMachineOperatorFlags(),
InstructionSelector::AlignmentRequirements());
- JSGraph jsgraph(nullptr, &graph, &common, nullptr, nullptr, &machine);
+ MachineGraph mcgraph(&graph, &common, &machine);
Node* control = nullptr;
Node* effect = nullptr;
@@ -6355,7 +6576,7 @@ wasm::WasmCompilationResult CompileWasmImportCallWrapper(
SourcePositionTable* source_position_table =
source_positions ? new (&zone) SourcePositionTable(&graph) : nullptr;
- WasmWrapperGraphBuilder builder(&zone, &jsgraph, sig, source_position_table,
+ WasmWrapperGraphBuilder builder(&zone, &mcgraph, sig, source_position_table,
StubCallMode::kCallWasmRuntimeStub,
env->enabled_features);
builder.set_control_ptr(&control);
@@ -6372,7 +6593,7 @@ wasm::WasmCompilationResult CompileWasmImportCallWrapper(
incoming = GetI32WasmCallDescriptor(&zone, incoming);
}
wasm::WasmCompilationResult result = Pipeline::GenerateCodeForWasmNativeStub(
- wasm_engine, incoming, &jsgraph, Code::WASM_TO_JS_FUNCTION,
+ wasm_engine, incoming, &mcgraph, Code::WASM_TO_JS_FUNCTION,
wasm::WasmCode::kWasmToJsWrapper, func_name, WasmStubAssemblerOptions(),
source_position_table);
result.kind = wasm::WasmCompilationResult::kWasmToJsWrapper;
@@ -6395,10 +6616,8 @@ wasm::WasmCode* CompileWasmCapiCallWrapper(wasm::WasmEngine* wasm_engine,
&zone, MachineType::PointerRepresentation(),
InstructionSelector::SupportedMachineOperatorFlags(),
InstructionSelector::AlignmentRequirements()));
- JSGraph jsgraph(nullptr, mcgraph->graph(), mcgraph->common(), nullptr,
- nullptr, mcgraph->machine());
- WasmWrapperGraphBuilder builder(&zone, &jsgraph, sig, source_positions,
+ WasmWrapperGraphBuilder builder(&zone, mcgraph, sig, source_positions,
StubCallMode::kCallWasmRuntimeStub,
native_module->enabled_features());
@@ -6448,12 +6667,12 @@ wasm::WasmCompilationResult CompileWasmInterpreterEntry(
&zone, MachineType::PointerRepresentation(),
InstructionSelector::SupportedMachineOperatorFlags(),
InstructionSelector::AlignmentRequirements());
- JSGraph jsgraph(nullptr, &graph, &common, nullptr, nullptr, &machine);
+ MachineGraph mcgraph(&graph, &common, &machine);
Node* control = nullptr;
Node* effect = nullptr;
- WasmWrapperGraphBuilder builder(&zone, &jsgraph, sig, nullptr,
+ WasmWrapperGraphBuilder builder(&zone, &mcgraph, sig, nullptr,
StubCallMode::kCallWasmRuntimeStub,
enabled_features);
builder.set_control_ptr(&control);
@@ -6471,7 +6690,7 @@ wasm::WasmCompilationResult CompileWasmInterpreterEntry(
SNPrintF(func_name, "wasm-interpreter-entry#%d", func_index));
wasm::WasmCompilationResult result = Pipeline::GenerateCodeForWasmNativeStub(
- wasm_engine, incoming, &jsgraph, Code::WASM_INTERPRETER_ENTRY,
+ wasm_engine, incoming, &mcgraph, Code::WASM_INTERPRETER_ENTRY,
wasm::WasmCode::kInterpreterEntry, func_name.begin(),
WasmStubAssemblerOptions());
result.result_tier = wasm::ExecutionTier::kInterpreter;
@@ -6480,6 +6699,54 @@ wasm::WasmCompilationResult CompileWasmInterpreterEntry(
return result;
}
+MaybeHandle<Code> CompileJSToJSWrapper(Isolate* isolate,
+ wasm::FunctionSig* sig) {
+ std::unique_ptr<Zone> zone =
+ base::make_unique<Zone>(isolate->allocator(), ZONE_NAME);
+ Graph* graph = new (zone.get()) Graph(zone.get());
+ CommonOperatorBuilder common(zone.get());
+ MachineOperatorBuilder machine(
+ zone.get(), MachineType::PointerRepresentation(),
+ InstructionSelector::SupportedMachineOperatorFlags(),
+ InstructionSelector::AlignmentRequirements());
+ MachineGraph mcgraph(graph, &common, &machine);
+
+ Node* control = nullptr;
+ Node* effect = nullptr;
+
+ WasmWrapperGraphBuilder builder(zone.get(), &mcgraph, sig, nullptr,
+ StubCallMode::kCallCodeObject,
+ wasm::WasmFeaturesFromIsolate(isolate));
+ builder.set_control_ptr(&control);
+ builder.set_effect_ptr(&effect);
+ builder.BuildJSToJSWrapper(isolate);
+
+ int wasm_count = static_cast<int>(sig->parameter_count());
+ CallDescriptor* incoming = Linkage::GetJSCallDescriptor(
+ zone.get(), false, wasm_count + 1, CallDescriptor::kNoFlags);
+
+ // Build a name in the form "js-to-js-wrapper:<params>:<returns>".
+ static constexpr size_t kMaxNameLen = 128;
+ auto debug_name = std::unique_ptr<char[]>(new char[kMaxNameLen]);
+ memcpy(debug_name.get(), "js-to-js-wrapper:", 18);
+ AppendSignature(debug_name.get(), kMaxNameLen, sig);
+
+ // Run the compilation job synchronously.
+ std::unique_ptr<OptimizedCompilationJob> job(
+ Pipeline::NewWasmHeapStubCompilationJob(
+ isolate, isolate->wasm_engine(), incoming, std::move(zone), graph,
+ Code::JS_TO_JS_FUNCTION, std::move(debug_name),
+ AssemblerOptions::Default(isolate)));
+
+ if (job->ExecuteJob() == CompilationJob::FAILED ||
+ job->FinalizeJob(isolate) == CompilationJob::FAILED) {
+ return {};
+ }
+ Handle<Code> code = job->compilation_info()->code();
+
+ return code;
+}
+
MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) {
std::unique_ptr<Zone> zone =
base::make_unique<Zone>(isolate->allocator(), ZONE_NAME);
@@ -6489,12 +6756,12 @@ MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) {
zone.get(), MachineType::PointerRepresentation(),
InstructionSelector::SupportedMachineOperatorFlags(),
InstructionSelector::AlignmentRequirements());
- JSGraph jsgraph(isolate, graph, &common, nullptr, nullptr, &machine);
+ MachineGraph mcgraph(graph, &common, &machine);
Node* control = nullptr;
Node* effect = nullptr;
- WasmWrapperGraphBuilder builder(zone.get(), &jsgraph, sig, nullptr,
+ WasmWrapperGraphBuilder builder(zone.get(), &mcgraph, sig, nullptr,
StubCallMode::kCallCodeObject,
wasm::WasmFeaturesFromIsolate(isolate));
builder.set_control_ptr(&control);
@@ -6510,9 +6777,9 @@ MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) {
MachineSignature incoming_sig(1, 4, sig_types);
// Traps need the root register, for TailCallRuntimeWithCEntry to call
// Runtime::kThrowWasmError.
- bool initialize_root_flag = true;
- CallDescriptor* incoming = Linkage::GetSimplifiedCDescriptor(
- zone.get(), &incoming_sig, initialize_root_flag);
+ CallDescriptor::Flags flags = CallDescriptor::kInitializeRootRegister;
+ CallDescriptor* incoming =
+ Linkage::GetSimplifiedCDescriptor(zone.get(), &incoming_sig, flags);
// Build a name in the form "c-wasm-entry:<params>:<returns>".
static constexpr size_t kMaxNameLen = 128;
@@ -6523,11 +6790,11 @@ MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) {
// Run the compilation job synchronously.
std::unique_ptr<OptimizedCompilationJob> job(
Pipeline::NewWasmHeapStubCompilationJob(
- isolate, incoming, std::move(zone), graph, Code::C_WASM_ENTRY,
- std::move(debug_name), AssemblerOptions::Default(isolate)));
+ isolate, isolate->wasm_engine(), incoming, std::move(zone), graph,
+ Code::C_WASM_ENTRY, std::move(debug_name),
+ AssemblerOptions::Default(isolate)));
- if (job->PrepareJob(isolate) == CompilationJob::FAILED ||
- job->ExecuteJob() == CompilationJob::FAILED ||
+ if (job->ExecuteJob() == CompilationJob::FAILED ||
job->FinalizeJob(isolate) == CompilationJob::FAILED) {
return {};
}
@@ -6536,6 +6803,8 @@ MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) {
return code;
}
+namespace {
+
bool BuildGraphForWasmFunction(AccountingAllocator* allocator,
wasm::CompilationEnv* env,
const wasm::FunctionBody& func_body,
@@ -6558,12 +6827,13 @@ bool BuildGraphForWasmFunction(AccountingAllocator* allocator,
return false;
}
- builder.LowerInt64();
+ builder.LowerInt64(WasmWrapperGraphBuilder::kCalledFromWasm);
if (builder.has_simd() &&
(!CpuFeatures::SupportsWasmSimd128() || env->lower_simd)) {
- SimdScalarLowering(mcgraph,
- CreateMachineSignature(mcgraph->zone(), func_body.sig))
+ SimdScalarLowering(
+ mcgraph, CreateMachineSignature(mcgraph->zone(), func_body.sig,
+ WasmGraphBuilder::kCalledFromWasm))
.LowerGraph();
}
@@ -6574,7 +6844,6 @@ bool BuildGraphForWasmFunction(AccountingAllocator* allocator,
return true;
}
-namespace {
Vector<const char> GetDebugName(Zone* zone, int index) {
// TODO(herhut): Use name from module if available.
constexpr int kBufferLength = 24;
@@ -6587,6 +6856,7 @@ Vector<const char> GetDebugName(Zone* zone, int index) {
memcpy(index_name, name_vector.begin(), name_len);
return Vector<const char>(index_name, name_len);
}
+
} // namespace
wasm::WasmCompilationResult ExecuteTurbofanWasmCompilation(
@@ -6755,7 +7025,7 @@ CallDescriptor* GetWasmCallDescriptor(
wasm::kFpReturnRegisters);
int parameter_slots = params.NumStackSlots();
- if (kPadArguments) parameter_slots = RoundUp(parameter_slots, 2);
+ if (ShouldPadArguments(parameter_slots)) parameter_slots++;
rets.SetStackOffset(parameter_slots);
@@ -6803,7 +7073,7 @@ CallDescriptor* GetWasmCallDescriptor(
namespace {
CallDescriptor* ReplaceTypeInCallDescriptorWith(
- Zone* zone, CallDescriptor* call_descriptor, size_t num_replacements,
+ Zone* zone, const CallDescriptor* call_descriptor, size_t num_replacements,
MachineType input_type, MachineRepresentation output_type) {
size_t parameter_count = call_descriptor->ParameterCount();
size_t return_count = call_descriptor->ReturnCount();
@@ -6819,14 +7089,23 @@ CallDescriptor* ReplaceTypeInCallDescriptorWith(
}
if (parameter_count == call_descriptor->ParameterCount() &&
return_count == call_descriptor->ReturnCount()) {
- return call_descriptor;
+ return const_cast<CallDescriptor*>(call_descriptor);
}
LocationSignature::Builder locations(zone, return_count, parameter_count);
+ // The last parameter may be the special callable parameter. In that case we
+ // have to preserve it as the last parameter, i.e. we allocate it in the new
+ // location signature again in the same register.
+ bool has_callable_param =
+ (call_descriptor->GetInputLocation(call_descriptor->InputCount() - 1) ==
+ LinkageLocation::ForRegister(kJSFunctionRegister.code(),
+ MachineType::TaggedPointer()));
LinkageLocationAllocator params(wasm::kGpParamRegisters,
wasm::kFpParamRegisters);
- for (size_t i = 0; i < call_descriptor->ParameterCount(); i++) {
+ for (size_t i = 0, e = call_descriptor->ParameterCount() -
+ (has_callable_param ? 1 : 0);
+ i < e; i++) {
if (call_descriptor->GetParameterType(i) == input_type) {
for (size_t j = 0; j < num_replacements; j++) {
locations.AddParam(params.Next(output_type));
@@ -6836,6 +7115,10 @@ CallDescriptor* ReplaceTypeInCallDescriptorWith(
params.Next(call_descriptor->GetParameterType(i).representation()));
}
}
+ if (has_callable_param) {
+ locations.AddParam(LinkageLocation::ForRegister(
+ kJSFunctionRegister.code(), MachineType::TaggedPointer()));
+ }
LinkageLocationAllocator rets(wasm::kGpReturnRegisters,
wasm::kFpReturnRegisters);
@@ -6867,8 +7150,8 @@ CallDescriptor* ReplaceTypeInCallDescriptorWith(
}
} // namespace
-CallDescriptor* GetI32WasmCallDescriptor(Zone* zone,
- CallDescriptor* call_descriptor) {
+CallDescriptor* GetI32WasmCallDescriptor(
+ Zone* zone, const CallDescriptor* call_descriptor) {
return ReplaceTypeInCallDescriptorWith(zone, call_descriptor, 2,
MachineType::Int64(),
MachineRepresentation::kWord32);