[wasm] All strings are length-prefixed and inline
R=titzer@chromium.org Review URL: https://codereview.chromium.org/1781523002 Cr-Commit-Position: refs/heads/master@{#34637}
This commit is contained in:
parent
ca5deb1ff8
commit
ca0dbaece0
@ -2204,12 +2204,13 @@ void WasmGraphBuilder::Int64LoweringForTesting() {
|
||||
static void RecordFunctionCompilation(Logger::LogEventsAndTags tag,
|
||||
CompilationInfo* info,
|
||||
const char* message, uint32_t index,
|
||||
const char* func_name) {
|
||||
wasm::WasmName func_name) {
|
||||
Isolate* isolate = info->isolate();
|
||||
if (isolate->logger()->is_logging_code_events() ||
|
||||
isolate->cpu_profiler()->is_profiling()) {
|
||||
ScopedVector<char> buffer(128);
|
||||
SNPrintF(buffer, "%s#%d:%s", message, index, func_name);
|
||||
SNPrintF(buffer, "%s#%d:%.*s", message, index, func_name.length,
|
||||
func_name.name);
|
||||
Handle<String> name_str =
|
||||
isolate->factory()->NewStringFromAsciiChecked(buffer.start());
|
||||
Handle<String> script_str =
|
||||
@ -2312,8 +2313,9 @@ Handle<JSFunction> CompileJSToWasmWrapper(
|
||||
buffer.Dispose();
|
||||
}
|
||||
|
||||
RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, "js-to-wasm", index,
|
||||
module->module->GetName(func->name_offset));
|
||||
RecordFunctionCompilation(
|
||||
Logger::FUNCTION_TAG, &info, "js-to-wasm", index,
|
||||
module->module->GetName(func->name_offset, func->name_length));
|
||||
// Set the JSFunction's machine code.
|
||||
function->set_code(*code);
|
||||
}
|
||||
@ -2323,8 +2325,8 @@ Handle<JSFunction> CompileJSToWasmWrapper(
|
||||
Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module,
|
||||
Handle<JSFunction> function,
|
||||
wasm::FunctionSig* sig,
|
||||
const char* module_cstr,
|
||||
const char* function_cstr) {
|
||||
wasm::WasmName module_name,
|
||||
wasm::WasmName function_name) {
|
||||
//----------------------------------------------------------------------------
|
||||
// Create the Graph
|
||||
//----------------------------------------------------------------------------
|
||||
@ -2392,7 +2394,7 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module,
|
||||
}
|
||||
|
||||
RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, "wasm-to-js", 0,
|
||||
module_cstr);
|
||||
module_name);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
@ -2431,9 +2433,10 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate,
|
||||
}
|
||||
// Add the function as another context for the exception
|
||||
ScopedVector<char> buffer(128);
|
||||
SNPrintF(buffer, "Compiling WASM function #%d:%s failed:",
|
||||
function.func_index,
|
||||
module_env->module->GetName(function.name_offset));
|
||||
wasm::WasmName name =
|
||||
module_env->module->GetName(function.name_offset, function.name_length);
|
||||
SNPrintF(buffer, "Compiling WASM function #%d:%.*s failed:",
|
||||
function.func_index, name.length, name.name);
|
||||
thrower.Failed(buffer.start(), result);
|
||||
return Handle<Code>::null();
|
||||
}
|
||||
@ -2456,8 +2459,10 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate,
|
||||
Vector<char> buffer;
|
||||
if (debugging) {
|
||||
buffer = Vector<char>::New(128);
|
||||
SNPrintF(buffer, "WASM_function_#%d:%s", function.func_index,
|
||||
module_env->module->GetName(function.name_offset));
|
||||
wasm::WasmName name =
|
||||
module_env->module->GetName(function.name_offset, function.name_length);
|
||||
SNPrintF(buffer, "WASM_function_#%d:%.*s", function.func_index, name.length,
|
||||
name.name);
|
||||
func_name = buffer.start();
|
||||
}
|
||||
CompilationInfo info(func_name, isolate, &zone, flags);
|
||||
@ -2468,9 +2473,10 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate,
|
||||
buffer.Dispose();
|
||||
}
|
||||
if (!code.is_null()) {
|
||||
RecordFunctionCompilation(
|
||||
Logger::FUNCTION_TAG, &info, "WASM_function", function.func_index,
|
||||
module_env->module->GetName(function.name_offset));
|
||||
RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, "WASM_function",
|
||||
function.func_index,
|
||||
module_env->module->GetName(
|
||||
function.name_offset, function.name_length));
|
||||
}
|
||||
|
||||
return code;
|
||||
|
@ -41,8 +41,8 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate,
|
||||
Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module,
|
||||
Handle<JSFunction> function,
|
||||
wasm::FunctionSig* sig,
|
||||
const char* module_name,
|
||||
const char* function_name);
|
||||
wasm::WasmName module_name,
|
||||
wasm::WasmName function_name);
|
||||
|
||||
// Wraps a given wasm code object, producing a JSFunction that can be called
|
||||
// from JavaScript.
|
||||
|
@ -225,6 +225,8 @@ class Decoder {
|
||||
*length = static_cast<int>(pc_ - pos);
|
||||
if (pc_ == end && (b & 0x80)) {
|
||||
error(pc_ - 1, "varint too large");
|
||||
} else if (*length == 0) {
|
||||
error(pc_, "varint of length 0");
|
||||
} else {
|
||||
TRACE("= %u\n", result);
|
||||
}
|
||||
|
@ -187,7 +187,6 @@ void WasmFunctionBuilder::SetName(const unsigned char* name, int name_length) {
|
||||
for (int i = 0; i < name_length; i++) {
|
||||
name_.push_back(*(name + i));
|
||||
}
|
||||
name_.push_back('\0');
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,7 +293,10 @@ WasmFunctionEncoder::WasmFunctionEncoder(Zone* zone, LocalType return_type,
|
||||
uint32_t WasmFunctionEncoder::HeaderSize() const {
|
||||
uint32_t size = 3;
|
||||
if (!external_) size += 2;
|
||||
if (HasName()) size += 4;
|
||||
if (HasName()) {
|
||||
uint32_t name_size = NameSize();
|
||||
size += static_cast<uint32_t>(SizeOfVarInt(name_size)) + name_size;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@ -327,10 +329,10 @@ void WasmFunctionEncoder::Serialize(byte* buffer, byte** header,
|
||||
EmitUint16(header, signature_index_);
|
||||
|
||||
if (HasName()) {
|
||||
uint32_t name_offset = static_cast<uint32_t>(*body - buffer);
|
||||
EmitUint32(header, name_offset);
|
||||
std::memcpy(*body, &name_[0], name_.size());
|
||||
(*body) += name_.size();
|
||||
EmitVarInt(header, NameSize());
|
||||
for (size_t i = 0; i < name_.size(); ++i) {
|
||||
EmitUint8(header, name_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -524,7 +526,8 @@ WasmModuleIndex* WasmModuleWriter::WriteTo(Zone* zone) const {
|
||||
|
||||
sizes.AddSection(globals_.size());
|
||||
if (globals_.size() > 0) {
|
||||
sizes.Add(kDeclGlobalSize * globals_.size(), 0);
|
||||
/* These globals never have names, so are always 3 bytes. */
|
||||
sizes.Add(3 * globals_.size(), 0);
|
||||
}
|
||||
|
||||
sizes.AddSection(functions_.size());
|
||||
@ -571,7 +574,7 @@ WasmModuleIndex* WasmModuleWriter::WriteTo(Zone* zone) const {
|
||||
EmitVarInt(&header, globals_.size());
|
||||
|
||||
for (auto global : globals_) {
|
||||
EmitUint32(&header, 0);
|
||||
EmitVarInt(&header, 0); // Length of the global name.
|
||||
EmitUint8(&header, WasmOpcodes::MemTypeCodeFor(global.first));
|
||||
EmitUint8(&header, global.second);
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ class ModuleDecoder : public Decoder {
|
||||
if (failed()) break;
|
||||
TRACE("DecodeGlobal[%d] module+%d\n", i,
|
||||
static_cast<int>(pc_ - start_));
|
||||
module->globals.push_back({0, MachineType::Int32(), 0, false});
|
||||
module->globals.push_back({0, 0, MachineType::Int32(), 0, false});
|
||||
WasmGlobal* global = &module->globals.back();
|
||||
DecodeGlobalInModule(global);
|
||||
}
|
||||
@ -252,12 +252,13 @@ class ModuleDecoder : public Decoder {
|
||||
import->sig = module->signatures[import->sig_index];
|
||||
}
|
||||
const byte* pos = pc_;
|
||||
import->module_name_offset = consume_string("import module name");
|
||||
if (import->module_name_offset == 0) {
|
||||
import->module_name_offset = consume_string(
|
||||
&import->module_name_length, "import module name");
|
||||
if (import->module_name_length == 0) {
|
||||
error(pos, "import module name cannot be NULL");
|
||||
}
|
||||
import->function_name_offset =
|
||||
consume_string("import function name");
|
||||
import->function_name_offset = consume_string(
|
||||
&import->function_name_length, "import function name");
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -285,7 +286,7 @@ class ModuleDecoder : public Decoder {
|
||||
exp->func_index,
|
||||
static_cast<int>(module->functions.size()));
|
||||
}
|
||||
exp->name_offset = consume_string("export name");
|
||||
exp->name_offset = consume_string(&exp->name_length, "export name");
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -344,6 +345,7 @@ class ModuleDecoder : public Decoder {
|
||||
pc_ = start_;
|
||||
function->sig = consume_sig(); // read signature
|
||||
function->name_offset = 0; // ---- name
|
||||
function->name_length = 0; // ---- name length
|
||||
function->code_start_offset = off(pc_); // ---- code start
|
||||
function->code_end_offset = off(limit_); // ---- code end
|
||||
function->exported = false; // ---- exported
|
||||
@ -373,7 +375,7 @@ class ModuleDecoder : public Decoder {
|
||||
|
||||
// Decodes a single global entry inside a module starting at {pc_}.
|
||||
void DecodeGlobalInModule(WasmGlobal* global) {
|
||||
global->name_offset = consume_string("global name");
|
||||
global->name_offset = consume_string(&global->name_length, "global name");
|
||||
global->type = mem_type();
|
||||
global->offset = 0;
|
||||
global->exported = consume_u8("exported") != 0;
|
||||
@ -402,7 +404,8 @@ class ModuleDecoder : public Decoder {
|
||||
(decl_bits & kDeclFunctionImport) == 0 ? " body" : "");
|
||||
|
||||
if (decl_bits & kDeclFunctionName) {
|
||||
function->name_offset = consume_string("function name");
|
||||
function->name_offset =
|
||||
consume_string(&function->name_length, "function name");
|
||||
}
|
||||
|
||||
function->exported = decl_bits & kDeclFunctionExport;
|
||||
@ -505,11 +508,14 @@ class ModuleDecoder : public Decoder {
|
||||
return offset;
|
||||
}
|
||||
|
||||
// Reads a single 32-bit unsigned integer interpreted as an offset into the
|
||||
// data and validating the string there and advances.
|
||||
uint32_t consume_string(const char* name = nullptr) {
|
||||
// TODO(titzer): validate string
|
||||
return consume_offset(name ? name : "string");
|
||||
// Reads a length-prefixed string, checking that it is within bounds. Returns
|
||||
// the offset of the string, and the length as an out parameter.
|
||||
uint32_t consume_string(uint32_t* length, const char* name = nullptr) {
|
||||
int varint_length;
|
||||
*length = consume_u32v(&varint_length, "string length");
|
||||
uint32_t offset = static_cast<uint32_t>(pc_ - start_);
|
||||
consume_bytes(*length);
|
||||
return offset;
|
||||
}
|
||||
|
||||
// Reads a single 8-bit integer, interpreting it as a local type.
|
||||
|
@ -16,8 +16,11 @@
|
||||
#define WASM_MODULE_HEADER U32_LE(kWasmMagic), U32_LE(kWasmVersion)
|
||||
|
||||
#define SIG_INDEX(v) U16_LE(v)
|
||||
// TODO(binji): make SIG_INDEX match this.
|
||||
#define IMPORT_SIG_INDEX(v) U32V_1(v)
|
||||
#define FUNC_INDEX(v) U32V_1(v)
|
||||
#define NAME_OFFSET(v) U32_LE(v)
|
||||
#define NO_NAME U32V_1(0)
|
||||
#define NAME_LENGTH(v) U32V_1(v)
|
||||
|
||||
#define ZERO_ALIGNMENT 0
|
||||
#define ZERO_OFFSET 0
|
||||
|
@ -48,7 +48,9 @@ std::ostream& operator<<(std::ostream& os, const WasmFunctionName& pair) {
|
||||
os << "#" << pair.function_->func_index << ":";
|
||||
if (pair.function_->name_offset > 0) {
|
||||
if (pair.module_) {
|
||||
os << pair.module_->GetName(pair.function_->name_offset);
|
||||
WasmName name = pair.module_->GetName(pair.function_->name_offset,
|
||||
pair.function_->name_length);
|
||||
os.write(name.name, name.length);
|
||||
} else {
|
||||
os << "+" << pair.function_->func_index;
|
||||
}
|
||||
@ -280,14 +282,15 @@ WasmModule::WasmModule()
|
||||
|
||||
static MaybeHandle<JSFunction> ReportFFIError(ErrorThrower& thrower,
|
||||
const char* error, uint32_t index,
|
||||
const char* module_cstr,
|
||||
const char* function_cstr) {
|
||||
if (function_cstr) {
|
||||
thrower.Error("Import #%d module=\"%s\" function=\"%s\" error: %s", index,
|
||||
module_cstr, function_cstr, error);
|
||||
wasm::WasmName module_name,
|
||||
wasm::WasmName function_name) {
|
||||
if (function_name.name) {
|
||||
thrower.Error("Import #%d module=\"%.*s\" function=\"%.*s\" error: %s",
|
||||
index, module_name.length, module_name.name,
|
||||
function_name.length, function_name.name, error);
|
||||
} else {
|
||||
thrower.Error("Import #%d module=\"%s\" error: %s", index, module_cstr,
|
||||
error);
|
||||
thrower.Error("Import #%d module=\"%.*s\" error: %s", index,
|
||||
module_name.length, module_name.name, error);
|
||||
}
|
||||
thrower.Error("Import ");
|
||||
return MaybeHandle<JSFunction>();
|
||||
@ -295,35 +298,37 @@ static MaybeHandle<JSFunction> ReportFFIError(ErrorThrower& thrower,
|
||||
|
||||
static MaybeHandle<JSFunction> LookupFunction(
|
||||
ErrorThrower& thrower, Factory* factory, Handle<JSObject> ffi,
|
||||
uint32_t index, const char* module_cstr, const char* function_cstr) {
|
||||
uint32_t index, wasm::WasmName module_name, wasm::WasmName function_name) {
|
||||
if (ffi.is_null()) {
|
||||
return ReportFFIError(thrower, "FFI is not an object", index, module_cstr,
|
||||
function_cstr);
|
||||
return ReportFFIError(thrower, "FFI is not an object", index, module_name,
|
||||
function_name);
|
||||
}
|
||||
|
||||
// Look up the module first.
|
||||
Handle<String> name = factory->InternalizeUtf8String(module_cstr);
|
||||
Handle<String> name = factory->InternalizeUtf8String(
|
||||
Vector<const char>(module_name.name, module_name.length));
|
||||
MaybeHandle<Object> result = Object::GetProperty(ffi, name);
|
||||
if (result.is_null()) {
|
||||
return ReportFFIError(thrower, "module not found", index, module_cstr,
|
||||
function_cstr);
|
||||
return ReportFFIError(thrower, "module not found", index, module_name,
|
||||
function_name);
|
||||
}
|
||||
|
||||
Handle<Object> module = result.ToHandleChecked();
|
||||
|
||||
if (!module->IsJSReceiver()) {
|
||||
return ReportFFIError(thrower, "module is not an object or function", index,
|
||||
module_cstr, function_cstr);
|
||||
module_name, function_name);
|
||||
}
|
||||
|
||||
Handle<Object> function;
|
||||
if (function_cstr) {
|
||||
if (function_name.name) {
|
||||
// Look up the function in the module.
|
||||
Handle<String> name = factory->InternalizeUtf8String(function_cstr);
|
||||
Handle<String> name = factory->InternalizeUtf8String(
|
||||
Vector<const char>(function_name.name, function_name.length));
|
||||
MaybeHandle<Object> result = Object::GetProperty(module, name);
|
||||
if (result.is_null()) {
|
||||
return ReportFFIError(thrower, "function not found", index, module_cstr,
|
||||
function_cstr);
|
||||
return ReportFFIError(thrower, "function not found", index, module_name,
|
||||
function_name);
|
||||
}
|
||||
function = result.ToHandleChecked();
|
||||
} else {
|
||||
@ -332,8 +337,8 @@ static MaybeHandle<JSFunction> LookupFunction(
|
||||
}
|
||||
|
||||
if (!function->IsJSFunction()) {
|
||||
return ReportFFIError(thrower, "not a function", index, module_cstr,
|
||||
function_cstr);
|
||||
return ReportFFIError(thrower, "not a function", index, module_name,
|
||||
function_name);
|
||||
}
|
||||
|
||||
return Handle<JSFunction>::cast(function);
|
||||
@ -404,14 +409,16 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
|
||||
if (import_table.size() > 0) {
|
||||
instance.import_code.reserve(import_table.size());
|
||||
for (const WasmImport& import : import_table) {
|
||||
const char* module_cstr = GetNameOrNull(import.module_name_offset);
|
||||
const char* function_cstr = GetNameOrNull(import.function_name_offset);
|
||||
WasmName module_name =
|
||||
GetNameOrNull(import.module_name_offset, import.module_name_length);
|
||||
WasmName function_name = GetNameOrNull(import.function_name_offset,
|
||||
import.function_name_length);
|
||||
MaybeHandle<JSFunction> function = LookupFunction(
|
||||
thrower, factory, ffi, index, module_cstr, function_cstr);
|
||||
thrower, factory, ffi, index, module_name, function_name);
|
||||
if (function.is_null()) return MaybeHandle<JSObject>();
|
||||
Handle<Code> code = compiler::CompileWasmToJSWrapper(
|
||||
isolate, &module_env, function.ToHandleChecked(), import.sig,
|
||||
module_cstr, function_cstr);
|
||||
module_name, function_name);
|
||||
instance.import_code.push_back(code);
|
||||
index++;
|
||||
}
|
||||
@ -427,23 +434,26 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
|
||||
if (thrower.error()) break;
|
||||
DCHECK_EQ(index, func.func_index);
|
||||
|
||||
const char* cstr = GetName(func.name_offset);
|
||||
Handle<String> name = factory->InternalizeUtf8String(cstr);
|
||||
WasmName str = GetName(func.name_offset, func.name_length);
|
||||
WasmName str_null = {nullptr, 0};
|
||||
Handle<String> name = factory->InternalizeUtf8String(
|
||||
Vector<const char>(str.name, str.length));
|
||||
Handle<Code> code = Handle<Code>::null();
|
||||
Handle<JSFunction> function = Handle<JSFunction>::null();
|
||||
if (func.external) {
|
||||
// Lookup external function in FFI object.
|
||||
MaybeHandle<JSFunction> function =
|
||||
LookupFunction(thrower, factory, ffi, index, cstr, nullptr);
|
||||
LookupFunction(thrower, factory, ffi, index, str, str_null);
|
||||
if (function.is_null()) return MaybeHandle<JSObject>();
|
||||
code = compiler::CompileWasmToJSWrapper(isolate, &module_env,
|
||||
function.ToHandleChecked(),
|
||||
func.sig, cstr, nullptr);
|
||||
func.sig, str, str_null);
|
||||
} else {
|
||||
// Compile the function.
|
||||
code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func);
|
||||
if (code.is_null()) {
|
||||
thrower.Error("Compilation of #%d:%s failed.", index, cstr);
|
||||
thrower.Error("Compilation of #%d:%.*s failed.", index, str.length,
|
||||
str.name);
|
||||
return MaybeHandle<JSObject>();
|
||||
}
|
||||
if (func.exported) {
|
||||
@ -485,8 +495,9 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
|
||||
// Compile wrappers and add them to the exports object.
|
||||
for (const WasmExport& exp : export_table) {
|
||||
if (thrower.error()) break;
|
||||
const char* cstr = GetName(exp.name_offset);
|
||||
Handle<String> name = factory->InternalizeUtf8String(cstr);
|
||||
WasmName str = GetName(exp.name_offset, exp.name_length);
|
||||
Handle<String> name = factory->InternalizeUtf8String(
|
||||
Vector<const char>(str.name, str.length));
|
||||
Handle<Code> code = linker.GetFunctionCode(exp.func_index);
|
||||
Handle<JSFunction> function = compiler::CompileJSToWasmWrapper(
|
||||
isolate, &module_env, name, code, instance.js_object, exp.func_index);
|
||||
|
@ -57,7 +57,6 @@ enum WasmFunctionDeclBit {
|
||||
|
||||
// Constants for fixed-size elements within a module.
|
||||
static const size_t kDeclMemorySize = 3;
|
||||
static const size_t kDeclGlobalSize = 6;
|
||||
static const size_t kDeclDataSegmentSize = 13;
|
||||
|
||||
// Static representation of a WASM function.
|
||||
@ -66,6 +65,7 @@ struct WasmFunction {
|
||||
uint32_t func_index; // index into the function table.
|
||||
uint32_t sig_index; // index into the signature table.
|
||||
uint32_t name_offset; // offset in the module bytes of the name, if any.
|
||||
uint32_t name_length; // length in bytes of the name.
|
||||
uint32_t code_start_offset; // offset in the module bytes of code start.
|
||||
uint32_t code_end_offset; // offset in the module bytes of code end.
|
||||
uint16_t local_i32_count; // number of i32 local variables.
|
||||
@ -81,18 +81,22 @@ struct WasmImport {
|
||||
FunctionSig* sig; // signature of the function.
|
||||
uint32_t sig_index; // index into the signature table.
|
||||
uint32_t module_name_offset; // offset in module bytes of the module name.
|
||||
uint32_t module_name_length; // length in bytes of the module name.
|
||||
uint32_t function_name_offset; // offset in module bytes of the import name.
|
||||
uint32_t function_name_length; // length in bytes of the import name.
|
||||
};
|
||||
|
||||
// Static representation of an exported WASM function.
|
||||
struct WasmExport {
|
||||
uint32_t func_index; // index into the function table.
|
||||
uint32_t name_offset; // offset in module bytes of the name to export.
|
||||
uint32_t name_length; // length in bytes of the exported name.
|
||||
};
|
||||
|
||||
// Static representation of a wasm global variable.
|
||||
struct WasmGlobal {
|
||||
uint32_t name_offset; // offset in the module bytes of the name, if any.
|
||||
uint32_t name_length; // length in bytes of the global name.
|
||||
MachineType type; // type of the global.
|
||||
uint32_t offset; // offset from beginning of globals area.
|
||||
bool exported; // true if this global is exported.
|
||||
@ -134,18 +138,18 @@ struct WasmModule {
|
||||
|
||||
WasmModule();
|
||||
|
||||
// Get a pointer to a string stored in the module bytes representing a name.
|
||||
const char* GetName(uint32_t offset) const {
|
||||
if (offset == 0) return "<?>"; // no name.
|
||||
CHECK(BoundsCheck(offset, offset + 1));
|
||||
return reinterpret_cast<const char*>(module_start + offset);
|
||||
// Get a string stored in the module bytes representing a name.
|
||||
WasmName GetName(uint32_t offset, uint32_t length) const {
|
||||
if (length == 0) return {"<?>", 3}; // no name.
|
||||
CHECK(BoundsCheck(offset, offset + length));
|
||||
return {reinterpret_cast<const char*>(module_start + offset), length};
|
||||
}
|
||||
|
||||
// Get a pointer to a string stored in the module bytes representing a name.
|
||||
const char* GetNameOrNull(uint32_t offset) const {
|
||||
if (offset == 0) return nullptr; // no name.
|
||||
CHECK(BoundsCheck(offset, offset + 1));
|
||||
return reinterpret_cast<const char*>(module_start + offset);
|
||||
// Get a string stored in the module bytes representing a name.
|
||||
WasmName GetNameOrNull(uint32_t offset, uint32_t length) const {
|
||||
if (length == 0) return {NULL, 0}; // no name.
|
||||
CHECK(BoundsCheck(offset, offset + length));
|
||||
return {reinterpret_cast<const char*>(module_start + offset), length};
|
||||
}
|
||||
|
||||
// Checks the given offset range is contained within the module bytes.
|
||||
|
@ -49,6 +49,11 @@ const LocalType kAstEnd = MachineRepresentation::kTagged;
|
||||
typedef Signature<LocalType> FunctionSig;
|
||||
std::ostream& operator<<(std::ostream& os, const FunctionSig& function);
|
||||
|
||||
struct WasmName {
|
||||
const char* name;
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
// TODO(titzer): Renumber all the opcodes to fill in holes.
|
||||
|
||||
// Control expressions and blocks.
|
||||
|
@ -56,8 +56,10 @@ uint32_t AddJsFunction(TestingModule* module, FunctionSig* sig,
|
||||
module->AddFunction(sig, Handle<Code>::null());
|
||||
uint32_t index = static_cast<uint32_t>(module->module->functions.size() - 1);
|
||||
Isolate* isolate = CcTest::InitIsolateOnce();
|
||||
Handle<Code> code =
|
||||
CompileWasmToJSWrapper(isolate, module, jsfunc, sig, "test", nullptr);
|
||||
WasmName module_name = {"test", 4};
|
||||
WasmName function_name = {nullptr, 0};
|
||||
Handle<Code> code = CompileWasmToJSWrapper(isolate, module, jsfunc, sig,
|
||||
module_name, function_name);
|
||||
module->instance->function_code[index] = code;
|
||||
return index;
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ class TestingModule : public ModuleEnv {
|
||||
}
|
||||
uint32_t index = static_cast<uint32_t>(module->functions.size());
|
||||
module->functions.push_back(
|
||||
{sig, index, 0, 0, 0, 0, 0, 0, 0, false, false});
|
||||
{sig, index, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, false});
|
||||
instance->function_code.push_back(code);
|
||||
DCHECK_LT(index, kMaxFunctions); // limited for testing.
|
||||
return index;
|
||||
@ -209,7 +209,7 @@ class TestingModule : public ModuleEnv {
|
||||
WasmGlobal* AddGlobal(MachineType mem_type) {
|
||||
byte size = WasmOpcodes::MemSize(mem_type);
|
||||
global_offset = (global_offset + size - 1) & ~(size - 1); // align
|
||||
module->globals.push_back({0, mem_type, global_offset, false});
|
||||
module->globals.push_back({0, 0, mem_type, global_offset, false});
|
||||
global_offset += size;
|
||||
// limit number of globals.
|
||||
CHECK_LT(global_offset, kMaxGlobalsSize);
|
||||
|
@ -2,11 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
function StringRef(string) {
|
||||
this.pos = -1;
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
function DataRef(data) {
|
||||
this.pos = -1;
|
||||
this.data = data;
|
||||
@ -117,10 +112,10 @@ function emit_u32(bytes, val) {
|
||||
}
|
||||
|
||||
function emit_string(bytes, string) {
|
||||
bytes.push(new StringRef(string));
|
||||
bytes.push(0);
|
||||
bytes.push(0);
|
||||
bytes.push(0);
|
||||
emit_varint(bytes, string.length);
|
||||
for (var i = 0; i < string.length; i++) {
|
||||
emit_u8(bytes, string.charCodeAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
function emit_data_ref(bytes, string) {
|
||||
@ -179,11 +174,7 @@ WasmModuleBuilder.prototype.toArray = function(debug) {
|
||||
for (imp of this.imports) {
|
||||
emit_varint(bytes, imp.sig_index);
|
||||
emit_string(bytes, imp.module);
|
||||
if (imp.name == undefined) {
|
||||
emit_u32(bytes, 0);
|
||||
} else {
|
||||
emit_string(bytes, imp.name);
|
||||
}
|
||||
emit_string(bytes, imp.name || '');
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,21 +288,12 @@ WasmModuleBuilder.prototype.toArray = function(debug) {
|
||||
if (debug) print("emitting end @ " + bytes.length);
|
||||
emit_u8(bytes, kDeclEnd);
|
||||
|
||||
// Collect references and canonicalize strings.
|
||||
// Collect references.
|
||||
var strings = new Object();
|
||||
var data_segments = [];
|
||||
var count = 0;
|
||||
for (var i = 0; i < bytes.length; i++) {
|
||||
var b = bytes[i];
|
||||
if (b instanceof StringRef) {
|
||||
count++;
|
||||
var prev = strings[b.string];
|
||||
if (prev) {
|
||||
bytes[i] = prev;
|
||||
} else {
|
||||
strings[b.string] = b;
|
||||
}
|
||||
}
|
||||
if (b instanceof DataRef) {
|
||||
data_segments.push(b);
|
||||
count++;
|
||||
@ -319,18 +301,6 @@ WasmModuleBuilder.prototype.toArray = function(debug) {
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
// Emit strings.
|
||||
if (debug) print("emitting strings @ " + bytes.length);
|
||||
for (str in strings) {
|
||||
var ref = strings[str];
|
||||
if (!(ref instanceof StringRef)) continue;
|
||||
if (debug) print(" \"" + str + "\" @ " + bytes.length);
|
||||
ref.pos = bytes.length;
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
emit_u8(bytes, str.charCodeAt(i));
|
||||
}
|
||||
emit_u8(bytes, 0); // null terminator.
|
||||
}
|
||||
// Emit data.
|
||||
if (debug) print("emitting data @ " + bytes.length);
|
||||
for (ref of data_segments) {
|
||||
@ -342,7 +312,7 @@ WasmModuleBuilder.prototype.toArray = function(debug) {
|
||||
// Update references to strings and data.
|
||||
for (var i = 0; i < bytes.length; i++) {
|
||||
var b = bytes[i];
|
||||
if (b instanceof StringRef || b instanceof DataRef) {
|
||||
if (b instanceof DataRef) {
|
||||
bytes[i] = b.pos & 0xFF;
|
||||
bytes[i + 1] = (b.pos >> 8) & 0xFF;
|
||||
bytes[i + 2] = (b.pos >> 16) & 0xFF;
|
||||
|
@ -1013,7 +1013,7 @@ class TestModuleEnv : public ModuleEnv {
|
||||
linker = nullptr;
|
||||
}
|
||||
byte AddGlobal(MachineType mem_type) {
|
||||
mod.globals.push_back({0, mem_type, 0, false});
|
||||
mod.globals.push_back({0, 0, mem_type, 0, false});
|
||||
CHECK(mod.globals.size() <= 127);
|
||||
return static_cast<byte>(mod.globals.size() - 1);
|
||||
}
|
||||
|
@ -98,9 +98,9 @@ TEST_F(WasmModuleVerifyTest, OneGlobal) {
|
||||
static const byte data[] = {
|
||||
kDeclGlobals,
|
||||
1,
|
||||
NAME_OFFSET(0),
|
||||
kMemI32, // memory type
|
||||
0, // exported
|
||||
NAME_LENGTH(1), 'g', // name
|
||||
kMemI32, // memory type
|
||||
0, // exported
|
||||
};
|
||||
|
||||
{
|
||||
@ -113,7 +113,7 @@ TEST_F(WasmModuleVerifyTest, OneGlobal) {
|
||||
|
||||
WasmGlobal* global = &result.val->globals.back();
|
||||
|
||||
EXPECT_EQ(0, global->name_offset);
|
||||
EXPECT_EQ(1, global->name_length);
|
||||
EXPECT_EQ(MachineType::Int32(), global->type);
|
||||
EXPECT_EQ(0, global->offset);
|
||||
EXPECT_FALSE(global->exported);
|
||||
@ -152,9 +152,9 @@ static void AppendUint32v(std::vector<byte>& buffer, uint32_t val) {
|
||||
|
||||
TEST_F(WasmModuleVerifyTest, NGlobals) {
|
||||
static const byte data[] = {
|
||||
NAME_OFFSET(0), // name offset
|
||||
kMemI32, // memory type
|
||||
0, // exported
|
||||
NO_NAME, // name length
|
||||
kMemI32, // memory type
|
||||
0, // exported
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < 1000000; i = i * 13 + 1) {
|
||||
@ -172,26 +172,13 @@ TEST_F(WasmModuleVerifyTest, NGlobals) {
|
||||
}
|
||||
|
||||
|
||||
TEST_F(WasmModuleVerifyTest, GlobalWithInvalidNameOffset) {
|
||||
static const byte data[] = {
|
||||
kDeclGlobals,
|
||||
1, // declare one global
|
||||
NAME_OFFSET(300), // name offset
|
||||
kMemI32, // memory type
|
||||
0, // exported
|
||||
};
|
||||
|
||||
EXPECT_FAILURE(data);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(WasmModuleVerifyTest, GlobalWithInvalidMemoryType) {
|
||||
static const byte data[] = {
|
||||
kDeclGlobals,
|
||||
1, // declare one global
|
||||
NAME_OFFSET(0), // name offset
|
||||
33, // memory type
|
||||
0, // exported
|
||||
1, // declare one global
|
||||
NO_NAME, // name length
|
||||
33, // memory type
|
||||
0, // exported
|
||||
};
|
||||
|
||||
EXPECT_FAILURE(data);
|
||||
@ -202,12 +189,12 @@ TEST_F(WasmModuleVerifyTest, TwoGlobals) {
|
||||
static const byte data[] = {
|
||||
kDeclGlobals,
|
||||
2,
|
||||
NAME_OFFSET(0), // #0: name offset
|
||||
kMemF32, // memory type
|
||||
0, // exported
|
||||
NAME_OFFSET(0), // #1: name offset
|
||||
kMemF64, // memory type
|
||||
1, // exported
|
||||
NO_NAME, // #0: name length
|
||||
kMemF32, // memory type
|
||||
0, // exported
|
||||
NO_NAME, // #1: name length
|
||||
kMemF64, // memory type
|
||||
1, // exported
|
||||
};
|
||||
|
||||
{
|
||||
@ -221,12 +208,12 @@ TEST_F(WasmModuleVerifyTest, TwoGlobals) {
|
||||
WasmGlobal* g0 = &result.val->globals[0];
|
||||
WasmGlobal* g1 = &result.val->globals[1];
|
||||
|
||||
EXPECT_EQ(0, g0->name_offset);
|
||||
EXPECT_EQ(0, g0->name_length);
|
||||
EXPECT_EQ(MachineType::Float32(), g0->type);
|
||||
EXPECT_EQ(0, g0->offset);
|
||||
EXPECT_FALSE(g0->exported);
|
||||
|
||||
EXPECT_EQ(0, g1->name_offset);
|
||||
EXPECT_EQ(0, g1->name_length);
|
||||
EXPECT_EQ(MachineType::Float64(), g1->type);
|
||||
EXPECT_EQ(0, g1->offset);
|
||||
EXPECT_TRUE(g1->exported);
|
||||
@ -288,16 +275,16 @@ TEST_F(WasmModuleVerifyTest, FunctionWithoutSig) {
|
||||
static const byte data[] = {
|
||||
kDeclFunctions, 1,
|
||||
// func#0 ------------------------------------------------------
|
||||
SIG_INDEX(0), // signature index
|
||||
NAME_OFFSET(0), // name offset
|
||||
U32_LE(0), // code start offset
|
||||
U32_LE(0), // code end offset
|
||||
U16_LE(899), // local int32 count
|
||||
U16_LE(799), // local int64 count
|
||||
U16_LE(699), // local float32 count
|
||||
U16_LE(599), // local float64 count
|
||||
0, // exported
|
||||
1 // external
|
||||
SIG_INDEX(0), // signature index
|
||||
NO_NAME, // name length
|
||||
U32_LE(0), // code start offset
|
||||
U32_LE(0), // code end offset
|
||||
U16_LE(899), // local int32 count
|
||||
U16_LE(799), // local int64 count
|
||||
U16_LE(699), // local float32 count
|
||||
U16_LE(599), // local float64 count
|
||||
0, // exported
|
||||
1 // external
|
||||
};
|
||||
|
||||
ModuleResult result = DecodeModule(data, data + arraysize(data));
|
||||
@ -307,7 +294,7 @@ TEST_F(WasmModuleVerifyTest, FunctionWithoutSig) {
|
||||
|
||||
|
||||
TEST_F(WasmModuleVerifyTest, OneEmptyVoidVoidFunction) {
|
||||
const int kCodeStartOffset = 31;
|
||||
const int kCodeStartOffset = 30;
|
||||
const int kCodeEndOffset = kCodeStartOffset + 1;
|
||||
|
||||
static const byte data[] = {
|
||||
@ -317,13 +304,13 @@ TEST_F(WasmModuleVerifyTest, OneEmptyVoidVoidFunction) {
|
||||
// func#0 ------------------------------------------------------
|
||||
kDeclFunctions, 1,
|
||||
kDeclFunctionLocals | kDeclFunctionExport | kDeclFunctionName,
|
||||
SIG_INDEX(0), // signature index
|
||||
NAME_OFFSET(9), // name offset
|
||||
U16_LE(1466), // local int32 count
|
||||
U16_LE(1355), // local int64 count
|
||||
U16_LE(1244), // local float32 count
|
||||
U16_LE(1133), // local float64 count
|
||||
1, 0, // size
|
||||
SIG_INDEX(0), // signature index
|
||||
NAME_LENGTH(2), 'h', 'i', // name
|
||||
U16_LE(1466), // local int32 count
|
||||
U16_LE(1355), // local int64 count
|
||||
U16_LE(1244), // local float32 count
|
||||
U16_LE(1133), // local float64 count
|
||||
1, 0, // size
|
||||
kExprNop,
|
||||
};
|
||||
|
||||
@ -339,7 +326,8 @@ TEST_F(WasmModuleVerifyTest, OneEmptyVoidVoidFunction) {
|
||||
|
||||
WasmFunction* function = &result.val->functions.back();
|
||||
|
||||
EXPECT_EQ(9, function->name_offset);
|
||||
EXPECT_EQ(18, function->name_offset);
|
||||
EXPECT_EQ(2, function->name_length);
|
||||
EXPECT_EQ(kCodeStartOffset, function->code_start_offset);
|
||||
EXPECT_EQ(kCodeEndOffset, function->code_end_offset);
|
||||
|
||||
@ -373,7 +361,7 @@ TEST_F(WasmModuleVerifyTest, OneFunctionImported) {
|
||||
EXPECT_EQ(1, result.val->functions.size());
|
||||
WasmFunction* function = &result.val->functions.back();
|
||||
|
||||
EXPECT_EQ(0, function->name_offset);
|
||||
EXPECT_EQ(0, function->name_length);
|
||||
EXPECT_EQ(0, function->code_start_offset);
|
||||
EXPECT_EQ(0, function->code_end_offset);
|
||||
|
||||
@ -409,7 +397,7 @@ TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody) {
|
||||
EXPECT_EQ(1, result.val->functions.size());
|
||||
WasmFunction* function = &result.val->functions.back();
|
||||
|
||||
EXPECT_EQ(0, function->name_offset);
|
||||
EXPECT_EQ(0, function->name_length);
|
||||
EXPECT_EQ(kCodeStartOffset, function->code_start_offset);
|
||||
EXPECT_EQ(kCodeEndOffset, function->code_end_offset);
|
||||
|
||||
@ -449,7 +437,7 @@ TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody_WithLocals) {
|
||||
EXPECT_EQ(1, result.val->functions.size());
|
||||
WasmFunction* function = &result.val->functions.back();
|
||||
|
||||
EXPECT_EQ(0, function->name_offset);
|
||||
EXPECT_EQ(0, function->name_length);
|
||||
EXPECT_EQ(kCodeStartOffset, function->code_start_offset);
|
||||
EXPECT_EQ(kCodeEndOffset, function->code_end_offset);
|
||||
|
||||
@ -466,31 +454,29 @@ TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody_WithLocals) {
|
||||
|
||||
|
||||
TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) {
|
||||
static const byte kDeclMemorySize = 4;
|
||||
static const byte kCodeStartOffset =
|
||||
8 + 2 + kDeclMemorySize + kDeclGlobalSize + 4 + 2 + 17;
|
||||
static const byte kCodeStartOffset = 8 + 4 + 5 + 4 + 18;
|
||||
static const byte kCodeEndOffset = kCodeStartOffset + 3;
|
||||
|
||||
static const byte data[] = {
|
||||
kDeclMemory, 28, 28, 1,
|
||||
// global#0 --------------------------------------------------
|
||||
kDeclGlobals, 1, 0, 0, 0, 0, // name offset
|
||||
kMemU8, // memory type
|
||||
0, // exported
|
||||
kDeclGlobals, 1, 0, // name length
|
||||
kMemU8, // memory type
|
||||
0, // exported
|
||||
// sig#0 -----------------------------------------------------
|
||||
kDeclSignatures, 1, 0, 0, // void -> void
|
||||
// func#0 ----------------------------------------------------
|
||||
kDeclFunctions, 1, kDeclFunctionLocals | kDeclFunctionName, 0,
|
||||
0, // signature index
|
||||
9, 0, 0, 0, // name offset
|
||||
1, 2, // local int32 count
|
||||
3, 4, // local int64 count
|
||||
5, 6, // local float32 count
|
||||
7, 8, // local float64 count
|
||||
3, 0, // body size
|
||||
kExprNop, // func#0 body
|
||||
kExprNop, // func#0 body
|
||||
kExprNop, // func#0 body
|
||||
0, // signature index
|
||||
2, 'h', 'i', // name
|
||||
1, 2, // local int32 count
|
||||
3, 4, // local int64 count
|
||||
5, 6, // local float32 count
|
||||
7, 8, // local float64 count
|
||||
3, 0, // body size
|
||||
kExprNop, // func#0 body
|
||||
kExprNop, // func#0 body
|
||||
kExprNop, // func#0 body
|
||||
// segment#0 -------------------------------------------------
|
||||
kDeclDataSegments, 1, 0xae, 0xb3, 0x08, 0, // dest addr
|
||||
15, 0, 0, 0, // source offset
|
||||
@ -509,14 +495,15 @@ TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) {
|
||||
|
||||
WasmGlobal* global = &result.val->globals.back();
|
||||
|
||||
EXPECT_EQ(0, global->name_offset);
|
||||
EXPECT_EQ(0, global->name_length);
|
||||
EXPECT_EQ(MachineType::Uint8(), global->type);
|
||||
EXPECT_EQ(0, global->offset);
|
||||
EXPECT_FALSE(global->exported);
|
||||
|
||||
WasmFunction* function = &result.val->functions.back();
|
||||
|
||||
EXPECT_EQ(9, function->name_offset);
|
||||
EXPECT_EQ(27, function->name_offset);
|
||||
EXPECT_EQ(2, function->name_length);
|
||||
EXPECT_EQ(kCodeStartOffset, function->code_start_offset);
|
||||
EXPECT_EQ(kCodeEndOffset, function->code_end_offset);
|
||||
|
||||
@ -1033,10 +1020,7 @@ TEST_F(WasmModuleVerifyTest, UnknownSectionSkipped) {
|
||||
0, // one byte section
|
||||
kDeclGlobals,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, // name offset
|
||||
0, // name length
|
||||
kMemI32, // memory type
|
||||
0, // exported
|
||||
};
|
||||
@ -1049,7 +1033,7 @@ TEST_F(WasmModuleVerifyTest, UnknownSectionSkipped) {
|
||||
|
||||
WasmGlobal* global = &result.val->globals.back();
|
||||
|
||||
EXPECT_EQ(0, global->name_offset);
|
||||
EXPECT_EQ(0, global->name_length);
|
||||
EXPECT_EQ(MachineType::Int32(), global->type);
|
||||
EXPECT_EQ(0, global->offset);
|
||||
EXPECT_FALSE(global->exported);
|
||||
@ -1070,9 +1054,9 @@ TEST_F(WasmModuleVerifyTest, ImportTable_nosigs) {
|
||||
TEST_F(WasmModuleVerifyTest, ImportTable_invalid_sig) {
|
||||
static const byte data[] = {
|
||||
kDeclSignatures, 0, kDeclImportTable, 1,
|
||||
SIG_INDEX(0), // sig index
|
||||
NAME_OFFSET(1), // module name
|
||||
NAME_OFFSET(1), // function name
|
||||
IMPORT_SIG_INDEX(0), // sig index
|
||||
NAME_LENGTH(1), 'm', // module name
|
||||
NAME_LENGTH(1), 'f', // function name
|
||||
};
|
||||
EXPECT_FAILURE(data);
|
||||
}
|
||||
@ -1083,10 +1067,10 @@ TEST_F(WasmModuleVerifyTest, ImportTable_one_sig) {
|
||||
1,
|
||||
VOID_VOID_SIG,
|
||||
kDeclImportTable,
|
||||
1, // --
|
||||
U32V_1(0), // sig index
|
||||
NAME_OFFSET(1), // module name
|
||||
NAME_OFFSET(1) // function name
|
||||
1, // --
|
||||
IMPORT_SIG_INDEX(0), // sig index
|
||||
NAME_LENGTH(1), 'm', // module name
|
||||
NAME_LENGTH(1), 'f', // function name
|
||||
};
|
||||
EXPECT_VERIFIES(data);
|
||||
}
|
||||
@ -1097,10 +1081,10 @@ TEST_F(WasmModuleVerifyTest, ImportTable_invalid_module) {
|
||||
1,
|
||||
VOID_VOID_SIG,
|
||||
kDeclImportTable,
|
||||
1, // --
|
||||
SIG_INDEX(0), // sig index
|
||||
NAME_OFFSET(0), // module name
|
||||
NAME_OFFSET(1) // function name
|
||||
1, // --
|
||||
IMPORT_SIG_INDEX(0), // sig index
|
||||
NO_NAME, // module name
|
||||
NAME_LENGTH(1), 'f' // function name
|
||||
};
|
||||
EXPECT_FAILURE(data);
|
||||
}
|
||||
@ -1108,9 +1092,9 @@ TEST_F(WasmModuleVerifyTest, ImportTable_invalid_module) {
|
||||
TEST_F(WasmModuleVerifyTest, ImportTable_off_end) {
|
||||
static const byte data[] = {
|
||||
kDeclSignatures, 1, VOID_VOID_SIG, kDeclImportTable, 1,
|
||||
SIG_INDEX(0), // sig index
|
||||
NAME_OFFSET(1), // module name
|
||||
NAME_OFFSET(1), // function name
|
||||
IMPORT_SIG_INDEX(0), // sig index
|
||||
NAME_LENGTH(1), 'm', // module name
|
||||
NAME_LENGTH(1), 'f', // function name
|
||||
};
|
||||
|
||||
EXPECT_OFF_END_FAILURE(data, 5, sizeof(data));
|
||||
@ -1140,41 +1124,41 @@ TEST_F(WasmModuleVerifyTest, ExportTableOne) {
|
||||
EMPTY_FUNCTION(0), // --
|
||||
kDeclExportTable, 1, // exports
|
||||
FUNC_INDEX(0), // --
|
||||
NAME_OFFSET(0) // --
|
||||
NO_NAME // --
|
||||
};
|
||||
EXPECT_VERIFIES(data);
|
||||
}
|
||||
|
||||
TEST_F(WasmModuleVerifyTest, ExportTableTwo) {
|
||||
static const byte data[] = {
|
||||
kDeclSignatures, 1, // sigs
|
||||
VOID_VOID_SIG, // --
|
||||
kDeclFunctions, 1, // functions
|
||||
EMPTY_FUNCTION(0), // --
|
||||
kDeclExportTable, 2, // exports
|
||||
FUNC_INDEX(0), // --
|
||||
NAME_OFFSET(1), // --
|
||||
FUNC_INDEX(0), // --
|
||||
NAME_OFFSET(2) // --
|
||||
kDeclSignatures, 1, // sigs
|
||||
VOID_VOID_SIG, // --
|
||||
kDeclFunctions, 1, // functions
|
||||
EMPTY_FUNCTION(0), // --
|
||||
kDeclExportTable, 2, // exports
|
||||
FUNC_INDEX(0), // --
|
||||
NAME_LENGTH(4), 'n', 'a', 'm', 'e', // --
|
||||
FUNC_INDEX(0), // --
|
||||
NAME_LENGTH(3), 'n', 'o', 'm' // --
|
||||
};
|
||||
EXPECT_VERIFIES(data);
|
||||
}
|
||||
|
||||
TEST_F(WasmModuleVerifyTest, ExportTableThree) {
|
||||
static const byte data[] = {
|
||||
kDeclSignatures, 1, // sigs
|
||||
VOID_VOID_SIG, // --
|
||||
kDeclFunctions, 3, // functions
|
||||
EMPTY_FUNCTION(0), // --
|
||||
EMPTY_FUNCTION(0), // --
|
||||
EMPTY_FUNCTION(0), // --
|
||||
kDeclExportTable, 3, // exports
|
||||
FUNC_INDEX(0), // --
|
||||
NAME_OFFSET(1), // --
|
||||
FUNC_INDEX(1), // --
|
||||
NAME_OFFSET(2), // --
|
||||
FUNC_INDEX(2), // --
|
||||
NAME_OFFSET(2) // --
|
||||
kDeclSignatures, 1, // sigs
|
||||
VOID_VOID_SIG, // --
|
||||
kDeclFunctions, 3, // functions
|
||||
EMPTY_FUNCTION(0), // --
|
||||
EMPTY_FUNCTION(0), // --
|
||||
EMPTY_FUNCTION(0), // --
|
||||
kDeclExportTable, 3, // exports
|
||||
FUNC_INDEX(0), // --
|
||||
NAME_LENGTH(1), 'a', // --
|
||||
FUNC_INDEX(1), // --
|
||||
NAME_LENGTH(1), 'b', // --
|
||||
FUNC_INDEX(2), // --
|
||||
NAME_LENGTH(1), 'c' // --
|
||||
};
|
||||
EXPECT_VERIFIES(data);
|
||||
}
|
||||
@ -1182,15 +1166,15 @@ TEST_F(WasmModuleVerifyTest, ExportTableThree) {
|
||||
TEST_F(WasmModuleVerifyTest, ExportTableThreeOne) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
const byte data[] = {
|
||||
kDeclSignatures, 1, // sigs
|
||||
VOID_VOID_SIG, // --
|
||||
kDeclFunctions, 3, // functions
|
||||
EMPTY_FUNCTION(0), // --
|
||||
EMPTY_FUNCTION(0), // --
|
||||
EMPTY_FUNCTION(0), // --
|
||||
kDeclExportTable, 1, // exports
|
||||
FUNC_INDEX(i), // --
|
||||
NAME_OFFSET(1) // --
|
||||
kDeclSignatures, 1, // sigs
|
||||
VOID_VOID_SIG, // --
|
||||
kDeclFunctions, 3, // functions
|
||||
EMPTY_FUNCTION(0), // --
|
||||
EMPTY_FUNCTION(0), // --
|
||||
EMPTY_FUNCTION(0), // --
|
||||
kDeclExportTable, 1, // exports
|
||||
FUNC_INDEX(i), // --
|
||||
NAME_LENGTH(2), 'e', 'x', // --
|
||||
};
|
||||
|
||||
if (i < 3) {
|
||||
@ -1209,7 +1193,7 @@ TEST_F(WasmModuleVerifyTest, ExportTableOne_off_end) {
|
||||
EMPTY_FUNCTION(0), // --
|
||||
kDeclExportTable, 1, // exports
|
||||
FUNC_INDEX(0), // --
|
||||
NAME_OFFSET(0) // --
|
||||
NO_NAME // --
|
||||
};
|
||||
|
||||
for (int length = 13; length < sizeof(data); length++) {
|
||||
|
Loading…
Reference in New Issue
Block a user