Commit 7cd1a7f7 authored by titzer's avatar titzer Committed by Commit bot

[wasm] Remove the use of the "external" bit on OldFunctions section.

This is a first step to removing the support for the OldFunctions
section altogether, which will greatly simplify the encoder and remove
the need to do local variable remapping in asm->wasm.

R=bradnelson@chromium.org,aseemgarg@chromium.org
BUG=

Review-Url: https://codereview.chromium.org/1974933002
Cr-Commit-Position: refs/heads/master@{#36228}
parent 60fb6ea1
......@@ -3016,7 +3016,8 @@ class WasmCompilationUnit {
ok_ = job_->OptimizeGraph() == CompilationJob::SUCCEEDED;
// TODO(bradnelson): Improve histogram handling of size_t.
// TODO(ahaas): The counters are not thread-safe at the moment.
// isolate_->counters()->wasm_compile_function_peak_memory_bytes()->AddSample(
// isolate_->counters()->wasm_compile_function_peak_memory_bytes()
// ->AddSample(
// static_cast<int>(jsgraph->graph()->zone()->allocation_size()));
if (FLAG_trace_wasm_decode_time) {
......
......@@ -566,8 +566,9 @@ class AsmWasmBuilderImpl : public AstVisitor {
if (var->is_function()) {
uint16_t index = LookupOrInsertFunction(var);
builder_->FunctionAt(index)->Exported(1);
builder_->FunctionAt(index)
->SetName(raw_name->raw_data(), raw_name->length());
builder_->FunctionAt(index)->SetName(
reinterpret_cast<const char*>(raw_name->raw_data()),
raw_name->length());
}
}
}
......@@ -632,12 +633,11 @@ class AsmWasmBuilderImpl : public AstVisitor {
private:
class ImportedFunctionIndices : public ZoneObject {
public:
const unsigned char* name_;
const char* name_;
int name_length_;
WasmModuleBuilder::SignatureMap signature_to_index_;
ImportedFunctionIndices(const unsigned char* name, int name_length,
Zone* zone)
ImportedFunctionIndices(const char* name, int name_length, Zone* zone)
: name_(name), name_length_(name_length), signature_to_index_(zone) {}
};
ZoneHashMap table_;
......@@ -649,7 +649,7 @@ class AsmWasmBuilderImpl : public AstVisitor {
ZoneAllocationPolicy(builder->zone())),
builder_(builder) {}
void AddImport(Variable* v, const unsigned char* name, int name_length) {
void AddImport(Variable* v, const char* name, int name_length) {
ImportedFunctionIndices* indices = new (builder_->zone())
ImportedFunctionIndices(name, name_length, builder_->zone());
ZoneHashMap::Entry* entry = table_.LookupOrInsert(
......@@ -667,17 +667,9 @@ class AsmWasmBuilderImpl : public AstVisitor {
if (pos != indices->signature_to_index_.end()) {
return pos->second;
} else {
uint16_t index = builder_->builder_->AddFunction();
uint32_t index = builder_->builder_->AddImport(
indices->name_, indices->name_length_, sig);
indices->signature_to_index_[sig] = index;
WasmFunctionBuilder* function = builder_->builder_->FunctionAt(index);
function->External(1);
function->SetName(indices->name_, indices->name_length_);
if (sig->return_count() > 0) {
function->ReturnType(sig->GetReturn());
}
for (size_t i = 0; i < sig->parameter_count(); i++) {
function->AddParam(sig->GetParam(i));
}
return index;
}
}
......@@ -803,8 +795,9 @@ class AsmWasmBuilderImpl : public AstVisitor {
if (bounds_->get(target).lower->Is(Type::Function())) {
const AstRawString* name =
prop->key()->AsLiteral()->AsRawPropertyName();
imported_function_table_.AddImport(target->var(), name->raw_data(),
name->length());
imported_function_table_.AddImport(
target->var(), reinterpret_cast<const char*>(name->raw_data()),
name->length());
}
}
// Property values in module scope don't emit code, so return.
......@@ -1275,13 +1268,17 @@ class AsmWasmBuilderImpl : public AstVisitor {
}
index =
imported_function_table_.GetFunctionIndex(vp->var(), sig.Build());
VisitCallArgs(expr);
current_function_builder_->Emit(kExprCallImport);
current_function_builder_->EmitVarInt(expr->arguments()->length());
current_function_builder_->EmitVarInt(index);
} else {
index = LookupOrInsertFunction(vp->var());
VisitCallArgs(expr);
current_function_builder_->Emit(kExprCallFunction);
current_function_builder_->EmitVarInt(expr->arguments()->length());
current_function_builder_->EmitVarInt(index);
}
VisitCallArgs(expr);
current_function_builder_->Emit(kExprCallFunction);
current_function_builder_->EmitVarInt(expr->arguments()->length());
current_function_builder_->EmitVarInt(index);
break;
}
case Call::KEYED_PROPERTY_CALL: {
......
......@@ -104,7 +104,6 @@ WasmFunctionBuilder::WasmFunctionBuilder(Zone* zone)
: return_type_(kAstI32),
locals_(zone),
exported_(0),
external_(0),
body_(zone),
local_indices_(zone),
name_(zone) {}
......@@ -222,9 +221,7 @@ void WasmFunctionBuilder::EditVarIntImmediate(uint32_t offset,
void WasmFunctionBuilder::Exported(uint8_t flag) { exported_ = flag; }
void WasmFunctionBuilder::External(uint8_t flag) { external_ = flag; }
void WasmFunctionBuilder::SetName(const unsigned char* name, int name_length) {
void WasmFunctionBuilder::SetName(const char* name, int name_length) {
name_.clear();
if (name_length > 0) {
for (int i = 0; i < name_length; i++) {
......@@ -236,7 +233,7 @@ void WasmFunctionBuilder::SetName(const unsigned char* name, int name_length) {
WasmFunctionEncoder* WasmFunctionBuilder::Build(Zone* zone,
WasmModuleBuilder* mb) const {
WasmFunctionEncoder* e =
new (zone) WasmFunctionEncoder(zone, return_type_, exported_, external_);
new (zone) WasmFunctionEncoder(zone, return_type_, exported_);
uint16_t* var_index = zone->NewArray<uint16_t>(locals_.size());
IndexVars(e, var_index);
if (body_.size() > 0) {
......@@ -330,16 +327,12 @@ void WasmFunctionBuilder::IndexVars(WasmFunctionEncoder* e,
}
WasmFunctionEncoder::WasmFunctionEncoder(Zone* zone, LocalType return_type,
bool exported, bool external)
: params_(zone),
exported_(exported),
external_(external),
body_(zone),
name_(zone) {}
bool exported)
: params_(zone), exported_(exported), body_(zone), name_(zone) {}
uint32_t WasmFunctionEncoder::HeaderSize() const {
uint32_t size = 3;
if (!external_) size += 2;
size += 2;
if (HasName()) {
uint32_t name_size = NameSize();
size +=
......@@ -356,8 +349,7 @@ uint32_t WasmFunctionEncoder::BodySize(void) const {
local_decl.AddLocals(local_f32_count_, kAstF32);
local_decl.AddLocals(local_f64_count_, kAstF64);
return external_ ? 0
: static_cast<uint32_t>(body_.size() + local_decl.Size());
return static_cast<uint32_t>(body_.size() + local_decl.Size());
}
uint32_t WasmFunctionEncoder::NameSize() const {
......@@ -367,7 +359,6 @@ uint32_t WasmFunctionEncoder::NameSize() const {
void WasmFunctionEncoder::Serialize(byte* buffer, byte** header,
byte** body) const {
uint8_t decl_bits = (exported_ ? kDeclFunctionExport : 0) |
(external_ ? kDeclFunctionImport : 0) |
(HasName() ? kDeclFunctionName : 0);
EmitUint8(header, decl_bits);
......@@ -380,20 +371,18 @@ void WasmFunctionEncoder::Serialize(byte* buffer, byte** header,
}
}
if (!external_) {
// TODO(titzer): embed a LocalDeclEncoder in the WasmFunctionEncoder
LocalDeclEncoder local_decl;
local_decl.AddLocals(local_i32_count_, kAstI32);
local_decl.AddLocals(local_i64_count_, kAstI64);
local_decl.AddLocals(local_f32_count_, kAstF32);
local_decl.AddLocals(local_f64_count_, kAstF64);
// TODO(titzer): embed a LocalDeclEncoder in the WasmFunctionEncoder
LocalDeclEncoder local_decl;
local_decl.AddLocals(local_i32_count_, kAstI32);
local_decl.AddLocals(local_i64_count_, kAstI64);
local_decl.AddLocals(local_f32_count_, kAstF32);
local_decl.AddLocals(local_f64_count_, kAstF64);
EmitUint16(header, static_cast<uint16_t>(body_.size() + local_decl.Size()));
(*header) += local_decl.Emit(*header);
if (body_.size() > 0) {
std::memcpy(*header, &body_[0], body_.size());
(*header) += body_.size();
}
EmitUint16(header, static_cast<uint16_t>(body_.size() + local_decl.Size()));
(*header) += local_decl.Emit(*header);
if (body_.size() > 0) {
std::memcpy(*header, &body_[0], body_.size());
(*header) += body_.size();
}
}
......@@ -426,6 +415,7 @@ void WasmDataSegmentEncoder::Serialize(byte* buffer, byte** header,
WasmModuleBuilder::WasmModuleBuilder(Zone* zone)
: zone_(zone),
signatures_(zone),
imports_(zone),
functions_(zone),
data_segments_(zone),
indirect_functions_(zone),
......@@ -433,9 +423,9 @@ WasmModuleBuilder::WasmModuleBuilder(Zone* zone)
signature_map_(zone),
start_function_index_(-1) {}
uint16_t WasmModuleBuilder::AddFunction() {
uint32_t WasmModuleBuilder::AddFunction() {
functions_.push_back(new (zone_) WasmFunctionBuilder(zone_));
return static_cast<uint16_t>(functions_.size() - 1);
return static_cast<uint32_t>(functions_.size() - 1);
}
WasmFunctionBuilder* WasmModuleBuilder::FunctionAt(size_t index) {
......@@ -467,7 +457,7 @@ bool WasmModuleBuilder::CompareFunctionSigs::operator()(FunctionSig* a,
return false;
}
uint16_t WasmModuleBuilder::AddSignature(FunctionSig* sig) {
uint32_t WasmModuleBuilder::AddSignature(FunctionSig* sig) {
SignatureMap::iterator pos = signature_map_.find(sig);
if (pos != signature_map_.end()) {
return pos->second;
......@@ -483,12 +473,21 @@ void WasmModuleBuilder::AddIndirectFunction(uint16_t index) {
indirect_functions_.push_back(index);
}
uint32_t WasmModuleBuilder::AddImport(const char* name, int name_length,
FunctionSig* sig) {
imports_.push_back({AddSignature(sig), name, name_length});
return static_cast<uint32_t>(imports_.size() - 1);
}
void WasmModuleBuilder::MarkStartFunction(uint16_t index) {
start_function_index_ = index;
}
WasmModuleWriter* WasmModuleBuilder::Build(Zone* zone) {
WasmModuleWriter* writer = new (zone) WasmModuleWriter(zone);
for (auto import : imports_) {
writer->imports_.push_back(import);
}
for (auto function : functions_) {
writer->functions_.push_back(function->Build(zone, this));
}
......@@ -514,7 +513,8 @@ uint32_t WasmModuleBuilder::AddGlobal(MachineType type, bool exported) {
}
WasmModuleWriter::WasmModuleWriter(Zone* zone)
: functions_(zone),
: imports_(zone),
functions_(zone),
data_segments_(zone),
signatures_(zone),
indirect_functions_(zone),
......@@ -576,6 +576,18 @@ WasmModuleIndex* WasmModuleWriter::WriteTo(Zone* zone) const {
(unsigned)sizes.body_size);
}
if (imports_.size() > 0) {
sizes.AddSection(WasmSection::Code::ImportTable, imports_.size());
for (auto import : imports_) {
sizes.Add(LEBHelper::sizeof_u32v(import.sig_index), 0);
sizes.Add(LEBHelper::sizeof_u32v(import.name_length), 0);
sizes.Add(import.name_length, 0);
sizes.Add(1, 0);
}
TRACE("Size after imports: %u, %u\n", (unsigned)sizes.header_size,
(unsigned)sizes.body_size);
}
if (indirect_functions_.size() > 0) {
sizes.AddSection(WasmSection::Code::FunctionTable,
indirect_functions_.size());
......@@ -655,6 +667,20 @@ WasmModuleIndex* WasmModuleWriter::WriteTo(Zone* zone) const {
FixupSection(section, header);
}
// -- emit imports -----------------------------------------------------------
if (imports_.size() > 0) {
byte* section = EmitSection(WasmSection::Code::ImportTable, &header);
EmitVarInt(&header, imports_.size());
for (auto import : imports_) {
EmitVarInt(&header, import.sig_index);
EmitVarInt(&header, import.name_length);
std::memcpy(header, import.name, import.name_length);
header += import.name_length;
EmitVarInt(&header, 0);
}
FixupSection(section, header);
}
// -- emit functions ---------------------------------------------------------
if (functions_.size() > 0) {
byte* section = EmitSection(WasmSection::Code::OldFunctions, &header);
......
......@@ -28,8 +28,7 @@ class WasmFunctionEncoder : public ZoneObject {
void Serialize(byte* buffer, byte** header, byte** body) const;
private:
WasmFunctionEncoder(Zone* zone, LocalType return_type, bool exported,
bool external);
WasmFunctionEncoder(Zone* zone, LocalType return_type, bool exported);
friend class WasmFunctionBuilder;
uint16_t signature_index_;
ZoneVector<LocalType> params_;
......@@ -38,11 +37,10 @@ class WasmFunctionEncoder : public ZoneObject {
uint16_t local_f32_count_;
uint16_t local_f64_count_;
bool exported_;
bool external_;
ZoneVector<uint8_t> body_;
ZoneVector<char> name_;
bool HasName() const { return (exported_ || external_) && name_.size() > 0; }
bool HasName() const { return exported_ && name_.size() > 0; }
};
class WasmFunctionBuilder : public ZoneObject {
......@@ -64,8 +62,7 @@ class WasmFunctionBuilder : public ZoneObject {
uint32_t EmitEditableVarIntImmediate();
void EditVarIntImmediate(uint32_t offset, const uint32_t immediate);
void Exported(uint8_t flag);
void External(uint8_t flag);
void SetName(const unsigned char* name, int name_length);
void SetName(const char* name, int name_length);
WasmFunctionEncoder* Build(Zone* zone, WasmModuleBuilder* mb) const;
private:
......@@ -75,7 +72,6 @@ class WasmFunctionBuilder : public ZoneObject {
struct Type;
ZoneVector<Type> locals_;
uint8_t exported_;
uint8_t external_;
ZoneVector<uint8_t> body_;
ZoneVector<uint32_t> local_indices_;
ZoneVector<char> name_;
......@@ -109,6 +105,12 @@ class WasmModuleIndex : public ZoneObject {
const byte* end_;
};
struct WasmFunctionImport {
uint32_t sig_index;
const char* name;
int name_length;
};
class WasmModuleWriter : public ZoneObject {
public:
WasmModuleIndex* WriteTo(Zone* zone) const;
......@@ -116,6 +118,7 @@ class WasmModuleWriter : public ZoneObject {
private:
friend class WasmModuleBuilder;
explicit WasmModuleWriter(Zone* zone);
ZoneVector<WasmFunctionImport> imports_;
ZoneVector<WasmFunctionEncoder*> functions_;
ZoneVector<WasmDataSegmentEncoder*> data_segments_;
ZoneVector<FunctionSig*> signatures_;
......@@ -127,13 +130,14 @@ class WasmModuleWriter : public ZoneObject {
class WasmModuleBuilder : public ZoneObject {
public:
explicit WasmModuleBuilder(Zone* zone);
uint16_t AddFunction();
uint32_t AddFunction();
uint32_t AddGlobal(MachineType type, bool exported);
WasmFunctionBuilder* FunctionAt(size_t index);
void AddDataSegment(WasmDataSegmentEncoder* data);
uint16_t AddSignature(FunctionSig* sig);
uint32_t AddSignature(FunctionSig* sig);
void AddIndirectFunction(uint16_t index);
void MarkStartFunction(uint16_t index);
uint32_t AddImport(const char* name, int name_length, FunctionSig* sig);
WasmModuleWriter* Build(Zone* zone);
struct CompareFunctionSigs {
......@@ -144,6 +148,7 @@ class WasmModuleBuilder : public ZoneObject {
private:
Zone* zone_;
ZoneVector<FunctionSig*> signatures_;
ZoneVector<WasmFunctionImport> imports_;
ZoneVector<WasmFunctionBuilder*> functions_;
ZoneVector<WasmDataSegmentEncoder*> data_segments_;
ZoneVector<uint16_t> indirect_functions_;
......
......@@ -176,8 +176,7 @@ class ModuleDecoder : public Decoder {
0, // local_i64_count
0, // local_f32_count
0, // local_f64_count
false, // exported
false}); // external
false}); // exported
WasmFunction* function = &module->functions.back();
function->sig_index = consume_sig_index(module, &function->sig);
}
......@@ -235,8 +234,7 @@ class ModuleDecoder : public Decoder {
0, // local_i64_count
0, // local_f32_count
0, // local_f64_count
false, // exported
false}); // external
false}); // exported
WasmFunction* function = &module->functions.back();
DecodeFunctionInModule(module, function, false);
}
......@@ -244,10 +242,9 @@ class ModuleDecoder : public Decoder {
for (uint32_t i = 0; i < functions_count; i++) {
if (failed()) break;
WasmFunction* function = &module->functions[i];
if (!function->external) {
VerifyFunctionBody(i, &menv, function);
if (result_.failed())
error(result_.error_pc, result_.error_msg.get());
VerifyFunctionBody(i, &menv, function);
if (result_.failed()) {
error(result_.error_pc, result_.error_msg.get());
}
}
}
......@@ -474,7 +471,6 @@ class ModuleDecoder : public Decoder {
function->code_start_offset = off(pc_); // ---- code start
function->code_end_offset = off(limit_); // ---- code end
function->exported = false; // ---- exported
function->external = false; // ---- external
if (ok()) VerifyFunctionBody(0, module_env, function);
......@@ -523,13 +519,11 @@ class ModuleDecoder : public Decoder {
function->sig = module->signatures[function->sig_index];
}
TRACE(" +%d <function attributes:%s%s%s%s%s>\n",
TRACE(" +%d <function attributes:%s%s%s>\n",
static_cast<int>(pc_ - start_),
decl_bits & kDeclFunctionName ? " name" : "",
decl_bits & kDeclFunctionImport ? " imported" : "",
decl_bits & kDeclFunctionLocals ? " locals" : "",
decl_bits & kDeclFunctionExport ? " exported" : "",
(decl_bits & kDeclFunctionImport) == 0 ? " body" : "");
decl_bits & kDeclFunctionExport ? " exported" : "");
function->exported = decl_bits & kDeclFunctionExport;
......@@ -538,12 +532,6 @@ class ModuleDecoder : public Decoder {
consume_string(&function->name_length, function->exported);
}
// Imported functions have no locals or body.
if (decl_bits & kDeclFunctionImport) {
function->external = true;
return;
}
if (decl_bits & kDeclFunctionLocals) {
function->local_i32_count = consume_u16("i32 count");
function->local_i64_count = consume_u16("i64 count");
......
......@@ -504,12 +504,8 @@ void InitializeParallelCompilation(
}
for (uint32_t i = FLAG_skip_compiling_wasm_funcs; i < functions.size(); i++) {
if (!functions[i].external) {
compilation_units[i] = compiler::CreateWasmCompilationUnit(
&thrower, isolate, &module_env, &functions[i], i);
} else {
compilation_units[i] = nullptr;
}
compilation_units[i] = compiler::CreateWasmCompilationUnit(
&thrower, isolate, &module_env, &functions[i], i);
}
}
......@@ -564,9 +560,7 @@ void FinishCompilationUnits(
executed_units.pop();
}
int j = compiler::GetIndexOfWasmCompilationUnit(unit);
if (!module->functions[j].external) {
results[j] = compiler::FinishCompilation(unit);
}
results[j] = compiler::FinishCompilation(unit);
}
}
......@@ -585,39 +579,26 @@ bool FinishCompilation(Isolate* isolate, WasmModule* module,
DCHECK_EQ(i, func.func_index);
WasmName str = module->GetName(func.name_offset, func.name_length);
WasmName str_null = {nullptr, 0};
Handle<Code> code = Handle<Code>::null();
Handle<JSFunction> function = Handle<JSFunction>::null();
Handle<String> function_name = Handle<String>::null();
if (func.external) {
// Lookup external function in FFI object.
MaybeHandle<JSFunction> function =
LookupFunction(thrower, factory, ffi, i, str, str_null);
if (function.is_null()) {
return false;
}
code = compiler::CompileWasmToJSWrapper(isolate, &module_env,
function.ToHandleChecked(),
func.sig, str, str_null);
if (FLAG_wasm_num_compilation_tasks != 0) {
code = results[i];
} else {
if (FLAG_wasm_num_compilation_tasks != 0) {
code = results[i];
} else {
// Compile the function.
code = compiler::CompileWasmFunction(&thrower, isolate, &module_env,
&func);
}
if (code.is_null()) {
thrower.Error("Compilation of #%d:%.*s failed.", i, str.length(),
str.start());
return false;
}
if (func.exported) {
function_name = factory->InternalizeUtf8String(str);
function = compiler::CompileJSToWasmWrapper(
isolate, &module_env, function_name, code, instance.js_object, i);
record_code_size(total_code_size, function->code());
}
// Compile the function.
code =
compiler::CompileWasmFunction(&thrower, isolate, &module_env, &func);
}
if (code.is_null()) {
thrower.Error("Compilation of #%d:%.*s failed.", i, str.length(),
str.start());
return false;
}
if (func.exported) {
function_name = factory->InternalizeUtf8String(str);
function = compiler::CompileJSToWasmWrapper(
isolate, &module_env, function_name, code, instance.js_object, i);
record_code_size(total_code_size, function->code());
}
if (!code.is_null()) {
// Install the code into the linker table.
......@@ -954,19 +935,17 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, WasmModule* module) {
int main_index = 0;
for (const WasmFunction& func : module->functions) {
DCHECK_EQ(index, func.func_index);
if (!func.external) {
// Compile the function and install it in the code table.
Handle<Code> code =
compiler::CompileWasmFunction(&thrower, isolate, &module_env, &func);
if (!code.is_null()) {
if (func.exported) {
main_code = code;
main_index = index;
}
linker.Finish(index, code);
// Compile the function and install it in the code table.
Handle<Code> code =
compiler::CompileWasmFunction(&thrower, isolate, &module_env, &func);
if (!code.is_null()) {
if (func.exported) {
main_code = code;
main_index = index;
}
if (thrower.error()) return -1;
linker.Finish(index, code);
}
if (thrower.error()) return -1;
index++;
}
......
......@@ -96,7 +96,6 @@ struct WasmSection {
enum WasmFunctionDeclBit {
kDeclFunctionName = 0x01,
kDeclFunctionImport = 0x02,
kDeclFunctionLocals = 0x04,
kDeclFunctionExport = 0x08
};
......@@ -121,7 +120,6 @@ struct WasmFunction {
uint16_t local_f32_count; // number of f32 local variables.
uint16_t local_f64_count; // number of f64 local variables.
bool exported; // true if this function is exported.
bool external; // true if this function is externally supplied.
};
// Static representation of an imported WASM function.
......
......@@ -40,7 +40,7 @@ void testFunctionNameTable(Vector<Vector<const char>> names) {
if (func_index % 2) all_names.push_back('\0');
module.functions.push_back(
{nullptr, 0, 0, static_cast<uint32_t>(name_offset),
static_cast<uint32_t>(name.length()), 0, 0, 0, 0, 0, 0, false, false});
static_cast<uint32_t>(name.length()), 0, 0, 0, 0, 0, 0, false});
++func_index;
}
......
......@@ -168,8 +168,7 @@ class TestingModule : public ModuleEnv {
module->functions.reserve(kMaxFunctions);
}
uint32_t index = static_cast<uint32_t>(module->functions.size());
module->functions.push_back(
{sig, index, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, false});
module->functions.push_back({sig, index, 0, 0, 0, 0, 0, 0, 0, 0, 0, false});
instance->function_code.push_back(code);
DCHECK_LT(index, kMaxFunctions); // limited for testing.
return index;
......
......@@ -1181,8 +1181,7 @@ class TestModuleEnv : public ModuleEnv {
0, // local_i64_count
0, // local_f32_count
0, // local_f64_count
false, // exported
false}); // external
false}); // exported
CHECK(mod.functions.size() <= 127);
return static_cast<byte>(mod.functions.size() - 1);
}
......
......@@ -13,7 +13,7 @@ namespace internal {
namespace wasm {
#define EMPTY_FUNCTION(sig_index) 0, SIG_INDEX(sig_index), U16_LE(0)
#define EMPTY_FUNCTION_SIZE ((size_t)5)
#define SIZEOF_EMPTY_FUNCTION ((size_t)5)
#define EMPTY_BODY 0
#define SIZEOF_EMPTY_BODY ((size_t)1)
#define NOP_BODY 2, 0, kExprNop
......@@ -334,7 +334,7 @@ TEST_F(WasmModuleVerifyTest, FunctionWithoutSig) {
U16_LE(699), // local float32 count
U16_LE(599), // local float64 count
0, // exported
1 // external
0 // external
};
ModuleResult result = DecodeModule(data, data + arraysize(data));
......@@ -385,7 +385,6 @@ TEST_F(WasmModuleVerifyTest, OneEmptyVoidVoidFunction) {
EXPECT_EQ(1133, function->local_f64_count);
EXPECT_TRUE(function->exported);
EXPECT_FALSE(function->external);
if (result.val) delete result.val;
}
......@@ -393,37 +392,6 @@ TEST_F(WasmModuleVerifyTest, OneEmptyVoidVoidFunction) {
EXPECT_OFF_END_FAILURE(data, 16, sizeof(data));
}
TEST_F(WasmModuleVerifyTest, OneFunctionImported) {
static const byte data[] = {
// signatures
SIGNATURES_SECTION_VOID_VOID,
// functions
SECTION(OLD_FUNCTIONS, 4), 1,
// func#0 ------------------------------------------------------
kDeclFunctionImport, // no name, no locals, imported
SIG_INDEX(0),
};
ModuleResult result = DecodeModule(data, data + arraysize(data));
EXPECT_OK(result);
EXPECT_EQ(1, result.val->functions.size());
WasmFunction* function = &result.val->functions.back();
EXPECT_EQ(0, function->name_length);
EXPECT_EQ(0, function->code_start_offset);
EXPECT_EQ(0, function->code_end_offset);
EXPECT_EQ(0, function->local_i32_count);
EXPECT_EQ(0, function->local_i64_count);
EXPECT_EQ(0, function->local_f32_count);
EXPECT_EQ(0, function->local_f64_count);
EXPECT_FALSE(function->exported);
EXPECT_TRUE(function->external);
if (result.val) delete result.val;
}
TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody) {
static const byte kCodeStartOffset = 38;
static const byte kCodeEndOffset = kCodeStartOffset + 1;
......@@ -453,7 +421,6 @@ TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody) {
EXPECT_EQ(0, function->local_f64_count);
EXPECT_FALSE(function->exported);
EXPECT_FALSE(function->external);
if (result.val) delete result.val;
}
......@@ -490,7 +457,6 @@ TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody_WithLocals) {
EXPECT_EQ(2055, function->local_f64_count);
EXPECT_FALSE(function->exported);
EXPECT_FALSE(function->external);
if (result.val) delete result.val;
}
......@@ -555,7 +521,6 @@ TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) {
EXPECT_EQ(kCodeEndOffset, function->code_end_offset);
EXPECT_FALSE(function->exported);
EXPECT_FALSE(function->external);
WasmDataSegment* segment = &result.val->data_segments.back();
......@@ -691,15 +656,13 @@ TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidDest) {
}
}
// To make below tests for indirect calls much shorter.
#define FUNCTION(sig_index, external) kDeclFunctionImport, SIG_INDEX(sig_index)
TEST_F(WasmModuleVerifyTest, OneIndirectFunction) {
static const byte data[] = {
// sig#0 -------------------------------------------------------
SIGNATURES_SECTION_VOID_VOID,
// func#0 ------------------------------------------------------
SECTION(OLD_FUNCTIONS, 4), 1, FUNCTION(0, 0),
SECTION(OLD_FUNCTIONS, 1 + SIZEOF_EMPTY_FUNCTION), 1, // --
EMPTY_FUNCTION(0),
// indirect table ----------------------------------------------
SECTION(FUNCTION_TABLE, 2), 1, U32V_1(0)};
......@@ -722,10 +685,11 @@ TEST_F(WasmModuleVerifyTest, MultipleIndirectFunctions) {
SIG_ENTRY_v_v, // void -> void
SIG_ENTRY_v_x(kLocalI32), // void -> i32
// func#0 ------------------------------------------------------
SECTION(OLD_FUNCTIONS, 13), 4, FUNCTION(0, 1), // --
FUNCTION(1, 1), // --
FUNCTION(0, 1), // --
FUNCTION(1, 1), // --
SECTION(OLD_FUNCTIONS, 1 + 4 * SIZEOF_EMPTY_FUNCTION), 4, // --
EMPTY_FUNCTION(0), // --
EMPTY_FUNCTION(1), // --
EMPTY_FUNCTION(0), // --
EMPTY_FUNCTION(1), // --
// indirect table ----------------------------------------------
SECTION(FUNCTION_TABLE, 9), 8,
U32V_1(0), // --
......@@ -767,7 +731,8 @@ TEST_F(WasmModuleVerifyTest, IndirectFunctionInvalidIndex) {
// sig#0 -------------------------------------------------------
SIGNATURES_SECTION_VOID_VOID,
// functions ---------------------------------------------------
SECTION(OLD_FUNCTIONS, 4), 1, FUNCTION(0, 1),
SECTION(OLD_FUNCTIONS, 1 + SIZEOF_EMPTY_FUNCTION), 1, // --
EMPTY_FUNCTION(0),
// indirect table ----------------------------------------------
SECTION(FUNCTION_TABLE, 3), 1, 1, 0,
};
......@@ -929,7 +894,6 @@ TEST_F(WasmFunctionVerifyTest, Ok_v_v_empty) {
EXPECT_EQ(SIZEOF_SIG_ENTRY_v_v, function->code_start_offset);
EXPECT_EQ(arraysize(data), function->code_end_offset);
// TODO(titzer): verify encoding of local declarations
EXPECT_FALSE(function->external);
EXPECT_FALSE(function->exported);
}
......@@ -1165,7 +1129,7 @@ TEST_F(WasmModuleVerifyTest, ExportTable_empty1) {
static const byte data[] = {
// signatures
SIGNATURES_SECTION_VOID_VOID,
SECTION(OLD_FUNCTIONS, 1 + EMPTY_FUNCTION_SIZE),
SECTION(OLD_FUNCTIONS, 1 + SIZEOF_EMPTY_FUNCTION),
1,
EMPTY_FUNCTION(0),
SECTION(EXPORT_TABLE, 1),
......@@ -1199,7 +1163,7 @@ TEST_F(WasmModuleVerifyTest, ExportTableOne) {
static const byte data[] = {
// signatures
SIGNATURES_SECTION_VOID_VOID,
SECTION(OLD_FUNCTIONS, 1 + EMPTY_FUNCTION_SIZE),
SECTION(OLD_FUNCTIONS, 1 + SIZEOF_EMPTY_FUNCTION),
1, // functions
EMPTY_FUNCTION(0), // --
SECTION(EXPORT_TABLE, 3),
......@@ -1214,7 +1178,7 @@ TEST_F(WasmModuleVerifyTest, ExportTableTwo) {
static const byte data[] = {
// signatures
SIGNATURES_SECTION_VOID_VOID,
SECTION(OLD_FUNCTIONS, 1 + EMPTY_FUNCTION_SIZE),
SECTION(OLD_FUNCTIONS, 1 + SIZEOF_EMPTY_FUNCTION),
1, // functions
EMPTY_FUNCTION(0), // --
SECTION(EXPORT_TABLE, 12),
......@@ -1238,7 +1202,7 @@ TEST_F(WasmModuleVerifyTest, ExportTableThree) {
static const byte data[] = {
// signatures
SIGNATURES_SECTION_VOID_VOID,
SECTION(OLD_FUNCTIONS, 1 + 3 * EMPTY_FUNCTION_SIZE),
SECTION(OLD_FUNCTIONS, 1 + 3 * SIZEOF_EMPTY_FUNCTION),
3, // functions
EMPTY_FUNCTION(0), // --
EMPTY_FUNCTION(0), // --
......@@ -1263,7 +1227,7 @@ TEST_F(WasmModuleVerifyTest, ExportTableThreeOne) {
const byte data[] = {
// signatures
SIGNATURES_SECTION_VOID_VOID,
SECTION(OLD_FUNCTIONS, 1 + 3 * EMPTY_FUNCTION_SIZE),
SECTION(OLD_FUNCTIONS, 1 + 3 * SIZEOF_EMPTY_FUNCTION),
3, // functions
EMPTY_FUNCTION(0), // --
EMPTY_FUNCTION(0), // --
......@@ -1288,7 +1252,7 @@ TEST_F(WasmModuleVerifyTest, ExportTableOne_off_end) {
static const byte data[] = {
// signatures
SIGNATURES_SECTION_VOID_VOID,
SECTION(OLD_FUNCTIONS, 1 + EMPTY_FUNCTION_SIZE),
SECTION(OLD_FUNCTIONS, 1 + SIZEOF_EMPTY_FUNCTION),
1, // functions
EMPTY_FUNCTION(0), // --
SECTION(EXPORT_TABLE, 1 + 6),
......
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