Backed out changeset 1b3a45aebcaf (bug 1258972) for landing with wrong bugnumber

This commit is contained in:
Carsten "Tomcat" Book 2016-07-13 10:15:48 +02:00
parent 41cca25d10
commit 2fb495c645
12 changed files with 23 additions and 236 deletions

View File

@ -590,20 +590,6 @@ class AstElemSegment : public AstNode
typedef AstVector<AstElemSegment*> AstElemSegmentVector;
class AstStartFunc : public AstNode
{
AstRef func_;
public:
explicit AstStartFunc(AstRef func)
: func_(func)
{}
AstRef& func() {
return func_;
}
};
class AstModule : public AstNode
{
public:
@ -622,7 +608,6 @@ class AstModule : public AstNode
Maybe<AstResizable> table_;
Maybe<AstResizable> memory_;
ExportVector exports_;
Maybe<AstStartFunc> startFunc_;
FuncVector funcs_;
AstDataSegmentVector dataSegments_;
AstElemSegmentVector elemSegments_;
@ -677,18 +662,6 @@ class AstModule : public AstNode
const AstElemSegmentVector& elemSegments() const {
return elemSegments_;
}
bool hasStartFunc() const {
return !!startFunc_;
}
bool setStartFunc(AstStartFunc startFunc) {
if (startFunc_)
return false;
startFunc_.emplace(startFunc);
return true;
}
AstStartFunc& startFunc() {
return *startFunc_;
}
bool declare(AstSig&& sig, uint32_t* sigIndex) {
SigMap::AddPtr p = sigMap_.lookupForAdd(sig);
if (p) {

View File

@ -33,7 +33,6 @@ static const char FunctionSectionId[] = "function";
static const char TableSectionId[] = "table";
static const char MemorySectionId[] = "memory";
static const char ExportSectionId[] = "export";
static const char StartSectionId[] = "start";
static const char CodeSectionId[] = "code";
static const char ElemSectionId[] = "elem";
static const char DataSectionId[] = "data";

View File

@ -1086,39 +1086,6 @@ DecodeFunctionBody(Decoder& d, ModuleGenerator& mg, uint32_t funcIndex)
return mg.finishFuncDef(funcIndex, &fg);
}
static bool
DecodeStartSection(Decoder& d, ModuleGenerator& mg)
{
uint32_t sectionStart, sectionSize;
if (!d.startSection(StartSectionId, &sectionStart, &sectionSize))
return Fail(d, "failed to start section");
if (sectionStart == Decoder::NotStarted)
return true;
uint32_t startFuncIndex;
if (!d.readVarU32(&startFuncIndex))
return Fail(d, "failed to read start func index");
if (startFuncIndex >= mg.numFuncSigs())
return Fail(d, "unknown start function");
const DeclaredSig& sig = mg.funcSig(startFuncIndex);
if (sig.ret() != ExprType::Void)
return Fail(d, "start function must not return anything");
if (sig.args().length())
return Fail(d, "start function must be nullary");
if (!mg.setStartFunction(startFuncIndex))
return false;
if (!d.finishSection(sectionStart, sectionSize))
return Fail(d, "data section byte size mismatch");
return true;
}
static bool
DecodeCodeSection(Decoder& d, ModuleGenerator& mg)
{
@ -1424,9 +1391,6 @@ wasm::Compile(Bytes&& bytecode, CompileArgs&& args, UniqueChars* error)
if (!DecodeExportSection(d, newFormat, memoryExported, mg))
return nullptr;
if (!DecodeStartSection(d, mg))
return nullptr;
if (!DecodeCodeSection(d, mg))
return nullptr;

View File

@ -649,8 +649,6 @@ ModuleGenerator::funcImport(uint32_t funcImportIndex) const
bool
ModuleGenerator::declareExport(UniqueChars fieldName, uint32_t funcIndex, uint32_t* exportIndex)
{
MOZ_ASSERT(!exportMap_.hasStartFunction());
if (!exportMap_.fieldNames.append(Move(fieldName)))
return false;
@ -689,23 +687,6 @@ ModuleGenerator::addMemoryExport(UniqueChars fieldName)
exportMap_.fieldsToExports.append(MemoryExport);
}
bool
ModuleGenerator::setStartFunction(uint32_t funcIndex)
{
FuncIndexMap::AddPtr p = funcIndexToExport_.lookupForAdd(funcIndex);
if (p) {
exportMap_.setStartFunction(p->value());
return true;
}
Sig copy;
if (!copy.clone(funcSig(funcIndex)))
return false;
exportMap_.setStartFunction(metadata_->exports.length());
return metadata_->exports.emplaceBack(Move(copy), funcIndex);
}
bool
ModuleGenerator::startFuncDefs()
{

View File

@ -184,9 +184,6 @@ class MOZ_STACK_CLASS ModuleGenerator
MOZ_MUST_USE bool finishFuncDef(uint32_t funcIndex, FunctionGenerator* fg);
MOZ_MUST_USE bool finishFuncDefs();
// Start function:
bool setStartFunction(uint32_t funcIndex);
// Segments:
MOZ_MUST_USE bool addDataSegment(DataSegment s) { return dataSegments_.append(s); }
MOZ_MUST_USE bool addElemSegment(ElemSegment&& s);

View File

@ -30,7 +30,7 @@ class WasmInstanceObject;
namespace wasm {
class ExportMap;
struct ExportMap;
// Instance represents a wasm instance and provides all the support for runtime
// execution of code in the instance. Instances share various immutable data
@ -100,9 +100,9 @@ class Instance
bool profilingEnabled() const { return profilingEnabled_; }
const char* profilingLabel(uint32_t funcIndex) const { return funcLabels_[funcIndex].get(); }
// If the source binary was saved (by passing the bytecode to the
// constructor), this method will render the binary as text. Otherwise, a
// diagnostic string will be returned.
// If the source binary was saved (by passing the bytecode to 'create'),
// this method will render the binary as text. Otherwise, a diagnostic
// string will be returned.
JSString* createText(JSContext* cx);

View File

@ -162,8 +162,7 @@ size_t
ExportMap::serializedSize() const
{
return SerializedVectorSize(fieldNames) +
SerializedPodVectorSize(fieldsToExports) +
sizeof(uint32_t);
SerializedPodVectorSize(fieldsToExports);
}
uint8_t*
@ -171,7 +170,6 @@ ExportMap::serialize(uint8_t* cursor) const
{
cursor = SerializeVector(cursor, fieldNames);
cursor = SerializePodVector(cursor, fieldsToExports);
cursor = WriteScalar(cursor, startExportIndex);
return cursor;
}
@ -179,8 +177,7 @@ const uint8_t*
ExportMap::deserialize(const uint8_t* cursor)
{
(cursor = DeserializeVector(cursor, &fieldNames)) &&
(cursor = DeserializePodVector(cursor, &fieldsToExports)) &&
(cursor = ReadScalar(cursor, &startExportIndex));
(cursor = DeserializePodVector(cursor, &fieldsToExports));
return cursor;
}
@ -567,16 +564,6 @@ Module::instantiate(JSContext* cx,
Debugger::onNewWasmInstance(cx, instanceObj);
// Call the start function, if there's one. By specification, it does not
// take any arguments nor does it return a value, so just create a dummy
// arguments object.
if (exportMap_.hasStartFunction()) {
FixedInvokeArgs<0> args(cx);
if (!instanceObj->instance().callExport(cx, exportMap_.startFunctionExportIndex(), args))
return false;
}
return true;
}

View File

@ -111,38 +111,16 @@ typedef Vector<Import, 0, SystemAllocPolicy> ImportVector;
// - the sentinel value MemoryExport indicating an export of linear memory; or
// - the index of an export into the ExportVector in Metadata
//
// ExportMap also contains the start function's export index, which maps to the
// export that is called at each instantiation of a given module.
//
// ExportMap is built incrementally by ModuleGenerator and then stored immutably
// by Module.
static const uint32_t MemoryExport = UINT32_MAX;
static const uint32_t NO_START_FUNCTION = UINT32_MAX;
class ExportMap
struct ExportMap
{
uint32_t startExportIndex;
public:
CacheableCharsVector fieldNames;
Uint32Vector fieldsToExports;
ExportMap() : startExportIndex(NO_START_FUNCTION) {}
bool hasStartFunction() const {
return startExportIndex != NO_START_FUNCTION;
}
void setStartFunction(uint32_t index) {
MOZ_ASSERT(!hasStartFunction());
startExportIndex = index;
}
uint32_t startFunctionExportIndex() const {
MOZ_ASSERT(hasStartFunction());
return startExportIndex;
}
WASM_DECLARE_SERIALIZABLE(ExportMap)
};

View File

@ -90,6 +90,8 @@ class WasmToken
If,
Import,
Index,
UnsignedInteger,
SignedInteger,
Memory,
NegativeZero,
Load,
@ -106,8 +108,6 @@ class WasmToken
Return,
Segment,
SetLocal,
SignedInteger,
Start,
Store,
Table,
TernaryOpcode,
@ -116,7 +116,6 @@ class WasmToken
Type,
UnaryOpcode,
Unreachable,
UnsignedInteger,
ValueType
};
private:
@ -1321,8 +1320,6 @@ WasmTokenStream::next()
return WasmToken(WasmToken::SetLocal, begin, cur_);
if (consume(MOZ_UTF16("segment")))
return WasmToken(WasmToken::Segment, begin, cur_);
if (consume(MOZ_UTF16("start")))
return WasmToken(WasmToken::Start, begin, cur_);
break;
case 't':
@ -2408,21 +2405,6 @@ ParseMemory(WasmParseContext& c, WasmToken token, AstModule* module)
return true;
}
static bool
ParseStartFunc(WasmParseContext& c, WasmToken token, AstModule* module)
{
AstRef func;
if (!c.ts.matchRef(&func, c.error))
return false;
if (!module->setStartFunc(AstStartFunc(func))) {
c.ts.generateError(token, c.error);
return false;
}
return true;
}
static AstImport*
ParseImport(WasmParseContext& c, bool newFormat, AstModule* module)
{
@ -2573,11 +2555,6 @@ ParseModule(const char16_t* text, bool newFormat, LifoAlloc& lifo, UniqueChars*
return nullptr;
break;
}
case WasmToken::Start: {
if (!ParseStartFunc(c, section, module))
return nullptr;
break;
}
case WasmToken::Memory: {
if (!ParseMemory(c, section, module))
return nullptr;
@ -3091,11 +3068,6 @@ ResolveModule(LifoAlloc& lifo, AstModule* module, UniqueChars* error)
return false;
}
if (module->hasStartFunc()) {
if (!r.resolveFunction(module->startFunc().func()))
return false;
}
return true;
}
@ -3750,23 +3722,6 @@ EncodeFunctionBody(Encoder& e, AstFunc& func)
return true;
}
static bool
EncodeStartSection(Encoder& e, AstModule& module)
{
if (!module.hasStartFunc())
return true;
size_t offset;
if (!e.startSection(StartSectionId, &offset))
return false;
if (!e.writeVarU32(module.startFunc().func().index()))
return false;
e.finishSection(offset);
return true;
}
static bool
EncodeCodeSection(Encoder& e, AstModule& module)
{
@ -3918,9 +3873,6 @@ EncodeModule(AstModule& module, bool newFormat, Bytes* bytes)
if (!EncodeExportSection(e, newFormat, module))
return false;
if (!EncodeStartSection(e, module))
return false;
if (!EncodeCodeSection(e, module))
return false;

View File

@ -262,7 +262,7 @@ var tooBigNameSection = {
wasmEval(moduleWithSections([tooBigNameSection]));
// Checking stack trace.
function runStackTraceTest(namesContent, expectedName) {
function runStartTraceTest(namesContent, expectedName) {
var sections = [
sigSection([v2vSig]),
importSection([{sigIndex:0, module:"env", func:"callback"}]),
@ -281,15 +281,15 @@ function runStackTraceTest(namesContent, expectedName) {
assertEq(result, expectedName);
};
runStackTraceTest(null, 'wasm-function[0]');
runStackTraceTest([{name: 'test'}], 'test');
runStackTraceTest([{name: 'test', locals: [{name: 'var1'}, {name: 'var2'}]}], 'test');
runStackTraceTest([{name: 'test', locals: [{name: 'var1'}, {name: 'var2'}]}], 'test');
runStackTraceTest([{name: 'test1'}, {name: 'test2'}], 'test1');
runStackTraceTest([{name: 'test☃'}], 'test☃');
runStackTraceTest([{name: 'te\xE0\xFF'}], 'te\xE0\xFF');
runStackTraceTest([], 'wasm-function[0]');
runStartTraceTest(null, 'wasm-function[0]');
runStartTraceTest([{name: 'test'}], 'test');
runStartTraceTest([{name: 'test', locals: [{name: 'var1'}, {name: 'var2'}]}], 'test');
runStartTraceTest([{name: 'test', locals: [{name: 'var1'}, {name: 'var2'}]}], 'test');
runStartTraceTest([{name: 'test1'}, {name: 'test2'}], 'test1');
runStartTraceTest([{name: 'test☃'}], 'test☃');
runStartTraceTest([{name: 'te\xE0\xFF'}], 'te\xE0\xFF');
runStartTraceTest([], 'wasm-function[0]');
// Notice that invalid names section content shall not fail the parsing
runStackTraceTest([{nameLen: 100, name: 'test'}], 'wasm-function[0]'); // invalid name size
runStackTraceTest([{name: 'test', locals: [{nameLen: 40, name: 'var1'}]}], 'wasm-function[0]'); // invalid variable name size
runStackTraceTest([{name: ''}], 'wasm-function[0]'); // empty name
runStartTraceTest([{nameLen: 100, name: 'test'}], 'wasm-function[0]'); // invalid name size
runStartTraceTest([{name: 'test', locals: [{nameLen: 40, name: 'var1'}]}], 'wasm-function[0]'); // invalid variable name size
runStartTraceTest([{name: ''}], 'wasm-function[0]'); // empty name

View File

@ -1,2 +1,4 @@
// |jit-test| test-also-wasm-baseline
// TODO start opcode
quit();
var importedArgs = ['start.wast']; load(scriptdir + '../spec.js');

View File

@ -1,46 +0,0 @@
// |jit-test| test-also-wasm-baseline
load(libdir + "wasm.js");
assertErrorMessage(() => wasmEvalText('(module (func) (start 0) (start 0))'), SyntaxError, /wasm text error/);
assertErrorMessage(() => wasmEvalText('(module (func) (start 1))'), TypeError, /unknown start function/);
assertErrorMessage(() => wasmEvalText('(module (func) (start $unknown))'), SyntaxError, /label.*not found/);
assertErrorMessage(() => wasmEvalText('(module (func (param i32)) (start 0))'), TypeError, /must be nullary/);
assertErrorMessage(() => wasmEvalText('(module (func (param i32) (param f32)) (start 0))'), TypeError, /must be nullary/);
assertErrorMessage(() => wasmEvalText('(module (func (param i32) (param f32) (param f64)) (start 0))'), TypeError, /must be nullary/);
assertErrorMessage(() => wasmEvalText('(module (func (result f32)) (start 0))'), TypeError, /must not return anything/);
// Basic use case.
var count = 0;
function inc() { count++; }
var exports = wasmEvalText(`(module (import "inc" "") (func (param i32)) (func (call_import 0)) (start 1))`, { inc });
assertEq(count, 1);
assertEq(Object.keys(exports).length, 0);
count = 0;
exports = wasmEvalText(`(module (import "inc" "") (func $start (call_import 0)) (start $start) (export "" 0))`, { inc });
assertEq(count, 1);
assertEq(typeof exports, 'function');
assertEq(exports(), undefined);
assertEq(count, 2);
// New API.
const Module = WebAssembly.Module;
const Instance = WebAssembly.Instance;
const textToBinary = str => wasmTextToBinary(str, 'new-format');
count = 0;
const m = new Module(textToBinary('(module (import "inc" "") (func) (func (call_import 0)) (start 1) (export "" 1))'));
assertEq(count, 0);
assertErrorMessage(() => new Instance(m), TypeError, /no import object given/);
assertEq(count, 0);
const i1 = new Instance(m, { inc });
assertEq(count, 1);
i1.exports[""]();
assertEq(count, 2);
const i2 = new Instance(m, { inc });
assertEq(count, 3);