Commit bf1797b1 authored by clemensh's avatar clemensh Committed by Commit bot

[wasm] Pass byte position for trapping instructions

During ast decoding and turbofan graph construction, we explicitely pass
the byte offset for all instructions which potentially trap.
The byte offset is finally passed to the runtime function which throws
the actual error, but it is not used there yet.

The WasmGraphBuilder::Binop and Unop methods have a default value of -1
for the position, which allows for more compact code for all the
functions which assemble bigger snippets from the primitive operations.
Whenever the position is actually used for generating a trap, we
check that it is not negative.

R=titzer@chromium.org

Review-Url: https://codereview.chromium.org/1915123006
Cr-Commit-Position: refs/heads/master@{#35925}
parent ceca5ae3
This diff is collapsed.
......@@ -99,12 +99,14 @@ class WasmGraphBuilder {
Node* Float32Constant(float value);
Node* Float64Constant(double value);
Node* Constant(Handle<Object> value);
Node* Binop(wasm::WasmOpcode opcode, Node* left, Node* right);
Node* Unop(wasm::WasmOpcode opcode, Node* input);
Node* Binop(wasm::WasmOpcode opcode, Node* left, Node* right,
wasm::WasmCodePosition position = wasm::kNoCodePosition);
Node* Unop(wasm::WasmOpcode opcode, Node* input,
wasm::WasmCodePosition position = wasm::kNoCodePosition);
unsigned InputCount(Node* node);
bool IsPhiWithMerge(Node* phi, Node* merge);
void AppendToMerge(Node* merge, Node* from);
void AppendToPhi(Node* merge, Node* phi, Node* from);
void AppendToPhi(Node* phi, Node* from);
//-----------------------------------------------------------------------
// Operations that read and/or write {control} and {effect}.
......@@ -115,11 +117,14 @@ class WasmGraphBuilder {
Node* IfDefault(Node* sw);
Node* Return(unsigned count, Node** vals);
Node* ReturnVoid();
Node* Unreachable();
Node* CallDirect(uint32_t index, Node** args);
Node* CallImport(uint32_t index, Node** args);
Node* CallIndirect(uint32_t index, Node** args);
Node* Unreachable(wasm::WasmCodePosition position);
Node* CallDirect(uint32_t index, Node** args,
wasm::WasmCodePosition position);
Node* CallImport(uint32_t index, Node** args,
wasm::WasmCodePosition position);
Node* CallIndirect(uint32_t index, Node** args,
wasm::WasmCodePosition position);
void BuildJSToWasmWrapper(Handle<Code> wasm_code, wasm::FunctionSig* sig);
void BuildWasmToJSWrapper(Handle<JSFunction> function,
wasm::FunctionSig* sig);
......@@ -136,8 +141,9 @@ class WasmGraphBuilder {
Node* LoadGlobal(uint32_t index);
Node* StoreGlobal(uint32_t index, Node* val);
Node* LoadMem(wasm::LocalType type, MachineType memtype, Node* index,
uint32_t offset);
Node* StoreMem(MachineType type, Node* index, uint32_t offset, Node* val);
uint32_t offset, wasm::WasmCodePosition position);
Node* StoreMem(MachineType type, Node* index, uint32_t offset, Node* val,
wasm::WasmCodePosition position);
static void PrintDebugName(Node* node);
......@@ -154,7 +160,7 @@ class WasmGraphBuilder {
void Int64LoweringForTesting();
void SetSourcePosition(Node* node, int position);
void SetSourcePosition(Node* node, wasm::WasmCodePosition position);
private:
static const int kDefaultBufferSize = 16;
......@@ -184,13 +190,15 @@ class WasmGraphBuilder {
Node* String(const char* string);
Node* MemBuffer(uint32_t offset);
void BoundsCheckMem(MachineType memtype, Node* index, uint32_t offset);
void BoundsCheckMem(MachineType memtype, Node* index, uint32_t offset,
wasm::WasmCodePosition position);
Node* MaskShiftCount32(Node* node);
Node* MaskShiftCount64(Node* node);
Node* BuildCCall(MachineSignature* sig, Node** args);
Node* BuildWasmCall(wasm::FunctionSig* sig, Node** args);
Node* BuildWasmCall(wasm::FunctionSig* sig, Node** args,
wasm::WasmCodePosition position);
Node* BuildF32Neg(Node* input);
Node* BuildF64Neg(Node* input);
......@@ -200,10 +208,10 @@ class WasmGraphBuilder {
Node* BuildF32Max(Node* left, Node* right);
Node* BuildF64Min(Node* left, Node* right);
Node* BuildF64Max(Node* left, Node* right);
Node* BuildI32SConvertF32(Node* input);
Node* BuildI32SConvertF64(Node* input);
Node* BuildI32UConvertF32(Node* input);
Node* BuildI32UConvertF64(Node* input);
Node* BuildI32SConvertF32(Node* input, wasm::WasmCodePosition position);
Node* BuildI32SConvertF64(Node* input, wasm::WasmCodePosition position);
Node* BuildI32UConvertF32(Node* input, wasm::WasmCodePosition position);
Node* BuildI32UConvertF64(Node* input, wasm::WasmCodePosition position);
Node* BuildI32Ctz(Node* input);
Node* BuildI32Popcnt(Node* input);
Node* BuildI64Ctz(Node* input);
......@@ -248,23 +256,24 @@ class WasmGraphBuilder {
Node* BuildFloatToIntConversionInstruction(
Node* input, ExternalReference ref,
MachineRepresentation parameter_representation,
const MachineType result_type);
Node* BuildI64SConvertF32(Node* input);
Node* BuildI64UConvertF32(Node* input);
Node* BuildI64SConvertF64(Node* input);
Node* BuildI64UConvertF64(Node* input);
Node* BuildI32DivS(Node* left, Node* right);
Node* BuildI32RemS(Node* left, Node* right);
Node* BuildI32DivU(Node* left, Node* right);
Node* BuildI32RemU(Node* left, Node* right);
Node* BuildI64DivS(Node* left, Node* right);
Node* BuildI64RemS(Node* left, Node* right);
Node* BuildI64DivU(Node* left, Node* right);
Node* BuildI64RemU(Node* left, Node* right);
const MachineType result_type, wasm::WasmCodePosition position);
Node* BuildI64SConvertF32(Node* input, wasm::WasmCodePosition position);
Node* BuildI64UConvertF32(Node* input, wasm::WasmCodePosition position);
Node* BuildI64SConvertF64(Node* input, wasm::WasmCodePosition position);
Node* BuildI64UConvertF64(Node* input, wasm::WasmCodePosition position);
Node* BuildI32DivS(Node* left, Node* right, wasm::WasmCodePosition position);
Node* BuildI32RemS(Node* left, Node* right, wasm::WasmCodePosition position);
Node* BuildI32DivU(Node* left, Node* right, wasm::WasmCodePosition position);
Node* BuildI32RemU(Node* left, Node* right, wasm::WasmCodePosition position);
Node* BuildI64DivS(Node* left, Node* right, wasm::WasmCodePosition position);
Node* BuildI64RemS(Node* left, Node* right, wasm::WasmCodePosition position);
Node* BuildI64DivU(Node* left, Node* right, wasm::WasmCodePosition position);
Node* BuildI64RemU(Node* left, Node* right, wasm::WasmCodePosition position);
Node* BuildDiv64Call(Node* left, Node* right, ExternalReference ref,
MachineType result_type, int trap_zero);
MachineType result_type, int trap_zero,
wasm::WasmCodePosition position);
Node* BuildJavaScriptToNumber(Node* node, Node* context, Node* effect,
Node* control);
......
......@@ -98,10 +98,13 @@ RUNTIME_FUNCTION(Runtime_ThrowStackOverflow) {
RUNTIME_FUNCTION(Runtime_ThrowWasmError) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
DCHECK_EQ(2, args.length());
CONVERT_SMI_ARG_CHECKED(message_id, 0);
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewError(static_cast<MessageTemplate::Template>(message_id)));
CONVERT_SMI_ARG_CHECKED(byte_offset, 1);
USE(byte_offset); // TODO(clemensh): patch the stack trace with this offset
Handle<Object> error = isolate->factory()->NewError(
static_cast<MessageTemplate::Template>(message_id));
return isolate->Throw(*error);
}
RUNTIME_FUNCTION(Runtime_UnwindAndFindExceptionHandler) {
......
......@@ -284,7 +284,7 @@ namespace internal {
F(ThrowIteratorResultNotAnObject, 1, 1) \
F(ThrowGeneratorRunning, 0, 1) \
F(ThrowStackOverflow, 0, 1) \
F(ThrowWasmError, 1, 1) \
F(ThrowWasmError, 2, 1) \
F(PromiseRejectEvent, 3, 1) \
F(PromiseRevokeReject, 1, 1) \
F(StackGuard, 0, 1) \
......
......@@ -615,13 +615,13 @@ class SR_WasmDecoder : public WasmDecoder {
switch (sig->parameter_count()) {
case 1: {
Value val = Pop(0, sig->GetParam(0));
node = BUILD(Unop, opcode, val.node);
node = BUILD(Unop, opcode, val.node, position());
break;
}
case 2: {
Value rval = Pop(1, sig->GetParam(1));
Value lval = Pop(0, sig->GetParam(0));
node = BUILD(Binop, opcode, lval.node, rval.node);
node = BUILD(Binop, opcode, lval.node, rval.node, position());
break;
}
default:
......@@ -829,8 +829,7 @@ class SR_WasmDecoder : public WasmDecoder {
break;
}
case kExprUnreachable: {
// TODO(clemensh): add source position for unreachable
Push(kAstEnd, BUILD0(Unreachable));
Push(kAstEnd, BUILD(Unreachable, position()));
ssa_env_->Kill(SsaEnv::kControlEnd);
break;
}
......@@ -988,9 +987,9 @@ class SR_WasmDecoder : public WasmDecoder {
CallFunctionOperand operand(this, pc_);
if (Validate(pc_, operand)) {
TFNode** buffer = PopArgs(operand.sig);
TFNode* call = BUILD(CallDirect, operand.index, buffer);
TFNode* call =
BUILD(CallDirect, operand.index, buffer, position());
Push(GetReturnType(operand.sig), call);
AddSourcePosition(call, pc_);
}
len = 1 + operand.length;
break;
......@@ -1001,9 +1000,9 @@ class SR_WasmDecoder : public WasmDecoder {
TFNode** buffer = PopArgs(operand.sig);
Value index = Pop(0, kAstI32);
if (buffer) buffer[0] = index.node;
TFNode* call = BUILD(CallIndirect, operand.index, buffer);
TFNode* call =
BUILD(CallIndirect, operand.index, buffer, position());
Push(GetReturnType(operand.sig), call);
AddSourcePosition(call, pc_);
}
len = 1 + operand.length;
break;
......@@ -1012,9 +1011,9 @@ class SR_WasmDecoder : public WasmDecoder {
CallImportOperand operand(this, pc_);
if (Validate(pc_, operand)) {
TFNode** buffer = PopArgs(operand.sig);
TFNode* call = BUILD(CallImport, operand.index, buffer);
TFNode* call =
BUILD(CallImport, operand.index, buffer, position());
Push(GetReturnType(operand.sig), call);
AddSourcePosition(call, pc_);
}
len = 1 + operand.length;
break;
......@@ -1108,7 +1107,8 @@ class SR_WasmDecoder : public WasmDecoder {
int DecodeLoadMem(LocalType type, MachineType mem_type) {
MemoryAccessOperand operand(this, pc_);
Value index = Pop(0, kAstI32);
TFNode* node = BUILD(LoadMem, type, mem_type, index.node, operand.offset);
TFNode* node =
BUILD(LoadMem, type, mem_type, index.node, operand.offset, position());
Push(type, node);
return 1 + operand.length;
}
......@@ -1117,7 +1117,7 @@ class SR_WasmDecoder : public WasmDecoder {
MemoryAccessOperand operand(this, pc_);
Value val = Pop(1, type);
Value index = Pop(0, kAstI32);
BUILD(StoreMem, mem_type, index.node, operand.offset, val.node);
BUILD(StoreMem, mem_type, index.node, operand.offset, val.node, position());
Push(type, val.node);
return 1 + operand.length;
}
......@@ -1295,7 +1295,7 @@ class SR_WasmDecoder : public WasmDecoder {
builder_->AppendToMerge(merge, from->control);
// Merge effects.
if (builder_->IsPhiWithMerge(to->effect, merge)) {
builder_->AppendToPhi(merge, to->effect, from->effect);
builder_->AppendToPhi(to->effect, from->effect);
} else if (to->effect != from->effect) {
uint32_t count = builder_->InputCount(merge);
TFNode** effects = builder_->Buffer(count);
......@@ -1310,7 +1310,7 @@ class SR_WasmDecoder : public WasmDecoder {
TFNode* tnode = to->locals[i];
TFNode* fnode = from->locals[i];
if (builder_->IsPhiWithMerge(tnode, merge)) {
builder_->AppendToPhi(merge, tnode, fnode);
builder_->AppendToPhi(tnode, fnode);
} else if (tnode != fnode) {
uint32_t count = builder_->InputCount(merge);
TFNode** vals = builder_->Buffer(count);
......@@ -1333,7 +1333,7 @@ class SR_WasmDecoder : public WasmDecoder {
TFNode* CreateOrMergeIntoPhi(LocalType type, TFNode* merge, TFNode* tnode,
TFNode* fnode) {
if (builder_->IsPhiWithMerge(tnode, merge)) {
builder_->AppendToPhi(merge, tnode, fnode);
builder_->AppendToPhi(tnode, fnode);
} else if (tnode != fnode) {
uint32_t count = builder_->InputCount(merge);
TFNode** vals = builder_->Buffer(count);
......@@ -1468,12 +1468,10 @@ class SR_WasmDecoder : public WasmDecoder {
return assigned;
}
void AddSourcePosition(TFNode* node, const byte* pc) {
if (node) {
int offset = static_cast<int>(pc - start_);
DCHECK_EQ(pc - start_, offset); // overflows cannot happen
builder_->SetSourcePosition(node, offset);
}
inline wasm::WasmCodePosition position() {
int offset = static_cast<int>(pc_ - start_);
DCHECK_EQ(pc_ - start_, offset); // overflows cannot happen
return offset;
}
};
......
......@@ -51,6 +51,9 @@ std::ostream& operator<<(std::ostream& os, const FunctionSig& function);
typedef Vector<const char> WasmName;
typedef int WasmCodePosition;
const WasmCodePosition kNoCodePosition = -1;
// Control expressions and blocks.
#define FOREACH_CONTROL_OPCODE(V) \
V(Nop, 0x00, _) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment