Commit 73a23146 authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[wasm][anyref] Implement the RefNull opcode

R=titzer@chromium.org

Bug: v8:7581
Change-Id: I3a1fcffd3429907bcf9f92a904ab30568e6d4d07
Reviewed-on: https://chromium-review.googlesource.com/998914
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52501}
parent c1c40d39
...@@ -97,12 +97,13 @@ bool ContainsSimd(wasm::FunctionSig* sig) { ...@@ -97,12 +97,13 @@ bool ContainsSimd(wasm::FunctionSig* sig) {
WasmGraphBuilder::WasmGraphBuilder( WasmGraphBuilder::WasmGraphBuilder(
ModuleEnv* env, Zone* zone, JSGraph* jsgraph, Handle<Code> centry_stub, ModuleEnv* env, Zone* zone, JSGraph* jsgraph, Handle<Code> centry_stub,
wasm::FunctionSig* sig, Handle<Oddball> anyref_null, wasm::FunctionSig* sig,
compiler::SourcePositionTable* source_position_table, compiler::SourcePositionTable* source_position_table,
RuntimeExceptionSupport exception_support) RuntimeExceptionSupport exception_support)
: zone_(zone), : zone_(zone),
jsgraph_(jsgraph), jsgraph_(jsgraph),
centry_stub_node_(jsgraph_->HeapConstant(centry_stub)), centry_stub_node_(jsgraph_->HeapConstant(centry_stub)),
anyref_null_node_(jsgraph_->HeapConstant(anyref_null)),
env_(env), env_(env),
cur_buffer_(def_buffer_), cur_buffer_(def_buffer_),
cur_bufsize_(kDefaultBufferSize), cur_bufsize_(kDefaultBufferSize),
...@@ -4664,7 +4665,8 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::WasmModule* module, ...@@ -4664,7 +4665,8 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::WasmModule* module,
ModuleEnv env(module, use_trap_handler); ModuleEnv env(module, use_trap_handler);
WasmGraphBuilder builder(&env, &zone, &jsgraph, WasmGraphBuilder builder(&env, &zone, &jsgraph,
CEntryStub(isolate, 1).GetCode(), func->sig); CEntryStub(isolate, 1).GetCode(),
isolate->factory()->null_value(), func->sig);
builder.set_control_ptr(&control); builder.set_control_ptr(&control);
builder.set_effect_ptr(&effect); builder.set_effect_ptr(&effect);
builder.BuildJSToWasmWrapper(weak_instance, wasm_code); builder.BuildJSToWasmWrapper(weak_instance, wasm_code);
...@@ -4776,9 +4778,9 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target, ...@@ -4776,9 +4778,9 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target,
: nullptr; : nullptr;
ModuleEnv env(nullptr, use_trap_handler); ModuleEnv env(nullptr, use_trap_handler);
WasmGraphBuilder builder(&env, &zone, &jsgraph, WasmGraphBuilder builder(
CEntryStub(isolate, 1).GetCode(), sig, &env, &zone, &jsgraph, CEntryStub(isolate, 1).GetCode(),
source_position_table); isolate->factory()->null_value(), sig, source_position_table);
builder.set_control_ptr(&control); builder.set_control_ptr(&control);
builder.set_effect_ptr(&effect); builder.set_effect_ptr(&effect);
builder.BuildWasmToJSWrapper(target, index); builder.BuildWasmToJSWrapper(target, index);
...@@ -4842,7 +4844,8 @@ Handle<Code> CompileWasmInterpreterEntry(Isolate* isolate, uint32_t func_index, ...@@ -4842,7 +4844,8 @@ Handle<Code> CompileWasmInterpreterEntry(Isolate* isolate, uint32_t func_index,
Node* effect = nullptr; Node* effect = nullptr;
WasmGraphBuilder builder(nullptr, &zone, &jsgraph, WasmGraphBuilder builder(nullptr, &zone, &jsgraph,
CEntryStub(isolate, 1).GetCode(), sig); CEntryStub(isolate, 1).GetCode(),
isolate->factory()->null_value(), sig);
builder.set_control_ptr(&control); builder.set_control_ptr(&control);
builder.set_effect_ptr(&effect); builder.set_effect_ptr(&effect);
builder.BuildWasmInterpreterEntry(func_index); builder.BuildWasmInterpreterEntry(func_index);
...@@ -4903,7 +4906,8 @@ Handle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) { ...@@ -4903,7 +4906,8 @@ Handle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) {
Node* effect = nullptr; Node* effect = nullptr;
WasmGraphBuilder builder(nullptr, &zone, &jsgraph, WasmGraphBuilder builder(nullptr, &zone, &jsgraph,
CEntryStub(isolate, 1).GetCode(), sig); CEntryStub(isolate, 1).GetCode(),
isolate->factory()->null_value(), sig);
builder.set_control_ptr(&control); builder.set_control_ptr(&control);
builder.set_effect_ptr(&effect); builder.set_effect_ptr(&effect);
builder.BuildCWasmEntry(); builder.BuildCWasmEntry();
...@@ -4977,8 +4981,12 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction( ...@@ -4977,8 +4981,12 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
SourcePositionTable* source_position_table = SourcePositionTable* source_position_table =
new (tf_.jsgraph_->zone()) SourcePositionTable(tf_.jsgraph_->graph()); new (tf_.jsgraph_->zone()) SourcePositionTable(tf_.jsgraph_->graph());
// We get the handle for {null_value()} directly from the isolate although we
// are on a background task because the handle is stored in the isolate
// anyways, and it is immortal and immovable.
WasmGraphBuilder builder(env_, tf_.jsgraph_->zone(), tf_.jsgraph_, WasmGraphBuilder builder(env_, tf_.jsgraph_->zone(), tf_.jsgraph_,
centry_stub_, func_body_.sig, source_position_table, centry_stub_, isolate_->factory()->null_value(),
func_body_.sig, source_position_table,
wasm_compilation_data_.runtime_exception_support()); wasm_compilation_data_.runtime_exception_support());
tf_.graph_construction_result_ = tf_.graph_construction_result_ =
wasm::BuildTFGraph(isolate_->allocator(), &builder, func_body_); wasm::BuildTFGraph(isolate_->allocator(), &builder, func_body_);
......
...@@ -229,7 +229,8 @@ class WasmGraphBuilder { ...@@ -229,7 +229,8 @@ class WasmGraphBuilder {
enum EnforceBoundsCheck : bool { kNeedsBoundsCheck, kCanOmitBoundsCheck }; enum EnforceBoundsCheck : bool { kNeedsBoundsCheck, kCanOmitBoundsCheck };
WasmGraphBuilder(ModuleEnv* env, Zone* zone, JSGraph* graph, WasmGraphBuilder(ModuleEnv* env, Zone* zone, JSGraph* graph,
Handle<Code> centry_stub, wasm::FunctionSig* sig, Handle<Code> centry_stub, Handle<Oddball> anyref_null,
wasm::FunctionSig* sig,
compiler::SourcePositionTable* spt = nullptr, compiler::SourcePositionTable* spt = nullptr,
RuntimeExceptionSupport res = kRuntimeExceptionSupport); RuntimeExceptionSupport res = kRuntimeExceptionSupport);
...@@ -264,6 +265,7 @@ class WasmGraphBuilder { ...@@ -264,6 +265,7 @@ class WasmGraphBuilder {
Node* IntPtrConstant(intptr_t value); Node* IntPtrConstant(intptr_t value);
Node* Float32Constant(float value); Node* Float32Constant(float value);
Node* Float64Constant(double value); Node* Float64Constant(double value);
Node* RefNull() { return anyref_null_node_; }
Node* HeapConstant(Handle<HeapObject> value); Node* HeapConstant(Handle<HeapObject> value);
Node* Binop(wasm::WasmOpcode opcode, Node* left, Node* right, Node* Binop(wasm::WasmOpcode opcode, Node* left, Node* right,
wasm::WasmCodePosition position = wasm::kNoCodePosition); wasm::WasmCodePosition position = wasm::kNoCodePosition);
...@@ -418,6 +420,7 @@ class WasmGraphBuilder { ...@@ -418,6 +420,7 @@ class WasmGraphBuilder {
Zone* const zone_; Zone* const zone_;
JSGraph* const jsgraph_; JSGraph* const jsgraph_;
Node* const centry_stub_node_; Node* const centry_stub_node_;
Node* const anyref_null_node_;
// env_ == nullptr means we're not compiling Wasm functions, such as for // env_ == nullptr means we're not compiling Wasm functions, such as for
// wrappers or interpreter stubs. // wrappers or interpreter stubs.
ModuleEnv* const env_ = nullptr; ModuleEnv* const env_ = nullptr;
......
...@@ -928,7 +928,9 @@ class LiftoffCompiler { ...@@ -928,7 +928,9 @@ class LiftoffCompiler {
__ PushRegister(kWasmF64, reg); __ PushRegister(kWasmF64, reg);
} }
void RefNull(Decoder* decoder, Value* result) { UNIMPLEMENTED(); } void RefNull(Decoder* decoder, Value* result) {
unsupported(decoder, "ref_null");
}
void Drop(Decoder* decoder, const Value& value) { void Drop(Decoder* decoder, const Value& value) {
__ DropStackSlot(&__ cache_state()->stack_state.back()); __ DropStackSlot(&__ cache_state()->stack_state.back());
......
...@@ -235,7 +235,7 @@ class WasmGraphBuildingInterface { ...@@ -235,7 +235,7 @@ class WasmGraphBuildingInterface {
} }
void RefNull(Decoder* decoder, Value* result) { void RefNull(Decoder* decoder, Value* result) {
result->node = builder_->HeapConstant(Handle<HeapObject>::null()); result->node = builder_->RefNull();
} }
void Drop(Decoder* decoder, const Value& value) {} void Drop(Decoder* decoder, const Value& value) {}
......
...@@ -684,7 +684,7 @@ WasmCode* NativeModule::AddCode( ...@@ -684,7 +684,7 @@ WasmCode* NativeModule::AddCode(
RelocInfo::Mode mode = it.rinfo()->rmode(); RelocInfo::Mode mode = it.rinfo()->rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) { if (mode == RelocInfo::EMBEDDED_OBJECT) {
Handle<HeapObject> p = it.rinfo()->target_object_handle(origin); Handle<HeapObject> p = it.rinfo()->target_object_handle(origin);
DCHECK_EQ(*p, p->GetIsolate()->heap()->undefined_value()); DCHECK(p->IsUndefined(p->GetIsolate()) || p->IsNull(p->GetIsolate()));
it.rinfo()->set_target_object(*p, SKIP_WRITE_BARRIER, SKIP_ICACHE_FLUSH); it.rinfo()->set_target_object(*p, SKIP_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
} else if (RelocInfo::IsCodeTarget(mode)) { } else if (RelocInfo::IsCodeTarget(mode)) {
// rewrite code handles to direct pointers to the first instruction in the // rewrite code handles to direct pointers to the first instruction in the
......
...@@ -270,13 +270,15 @@ void TestBuildingGraph( ...@@ -270,13 +270,15 @@ void TestBuildingGraph(
compiler::RuntimeExceptionSupport runtime_exception_support) { compiler::RuntimeExceptionSupport runtime_exception_support) {
if (module) { if (module) {
compiler::WasmGraphBuilder builder( compiler::WasmGraphBuilder builder(
module, zone, jsgraph, CEntryStub(jsgraph->isolate(), 1).GetCode(), sig, module, zone, jsgraph, CEntryStub(jsgraph->isolate(), 1).GetCode(),
source_position_table, runtime_exception_support); jsgraph->isolate()->factory()->null_value(), sig, source_position_table,
runtime_exception_support);
TestBuildingGraphWithBuilder(&builder, zone, sig, start, end); TestBuildingGraphWithBuilder(&builder, zone, sig, start, end);
} else { } else {
compiler::WasmGraphBuilder builder( compiler::WasmGraphBuilder builder(
nullptr, zone, jsgraph, CEntryStub(jsgraph->isolate(), 1).GetCode(), nullptr, zone, jsgraph, CEntryStub(jsgraph->isolate(), 1).GetCode(),
sig, source_position_table, runtime_exception_support); jsgraph->isolate()->factory()->null_value(), sig, source_position_table,
runtime_exception_support);
TestBuildingGraphWithBuilder(&builder, zone, sig, start, end); TestBuildingGraphWithBuilder(&builder, zone, sig, start, end);
} }
} }
......
...@@ -68,3 +68,16 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -68,3 +68,16 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
instance.exports.main({hello: 'world'}); instance.exports.main({hello: 'world'});
})(); })();
(function testAnyRefNull() {
print(arguments.callee.name);
const builder = new WasmModuleBuilder();
builder.addFunction('main', kSig_r_v)
.addBody([kExprRefNull])
.exportFunc();
const instance = builder.instantiate();
assertEquals(null, instance.exports.main());
})();
...@@ -136,6 +136,7 @@ let kSig_f_f = makeSig([kWasmF32], [kWasmF32]); ...@@ -136,6 +136,7 @@ let kSig_f_f = makeSig([kWasmF32], [kWasmF32]);
let kSig_d_d = makeSig([kWasmF64], [kWasmF64]); let kSig_d_d = makeSig([kWasmF64], [kWasmF64]);
let kSig_r_r = makeSig([kWasmAnyRef], [kWasmAnyRef]); let kSig_r_r = makeSig([kWasmAnyRef], [kWasmAnyRef]);
let kSig_v_r = makeSig([kWasmAnyRef], []); let kSig_v_r = makeSig([kWasmAnyRef], []);
let kSig_r_v = makeSig([], [kWasmAnyRef]);
function makeSig(params, results) { function makeSig(params, results) {
return {params: params, results: results}; return {params: params, results: results};
...@@ -189,6 +190,7 @@ let kExprI32Const = 0x41; ...@@ -189,6 +190,7 @@ let kExprI32Const = 0x41;
let kExprI64Const = 0x42; let kExprI64Const = 0x42;
let kExprF32Const = 0x43; let kExprF32Const = 0x43;
let kExprF64Const = 0x44; let kExprF64Const = 0x44;
let kExprRefNull = 0xd0;
let kExprI32LoadMem = 0x28; let kExprI32LoadMem = 0x28;
let kExprI64LoadMem = 0x29; let kExprI64LoadMem = 0x29;
let kExprF32LoadMem = 0x2a; let kExprF32LoadMem = 0x2a;
......
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