| Index: src/wasm/encoder.cc
|
| diff --git a/src/wasm/encoder.cc b/src/wasm/encoder.cc
|
| index 3ae2213ce636f37d6fcfb672eeb78ce5aa17efac..39a2f5aeb5b47849a63a81e64a5f41f58b406451 100644
|
| --- a/src/wasm/encoder.cc
|
| +++ b/src/wasm/encoder.cc
|
| @@ -95,18 +95,8 @@ byte* EmitSection(WasmSection::Code code, byte** b) {
|
| }
|
| } // namespace
|
|
|
| -struct WasmFunctionBuilder::Type {
|
| - bool param_;
|
| - LocalType type_;
|
| -};
|
| -
|
| WasmFunctionBuilder::WasmFunctionBuilder(Zone* zone)
|
| - : return_type_(kAstI32),
|
| - locals_(zone),
|
| - exported_(0),
|
| - body_(zone),
|
| - local_indices_(zone),
|
| - name_(zone) {}
|
| + : locals_(zone), exported_(0), body_(zone), name_(zone) {}
|
|
|
| void WasmFunctionBuilder::EmitVarInt(uint32_t val) {
|
| byte buffer[8];
|
| @@ -117,45 +107,28 @@ void WasmFunctionBuilder::EmitVarInt(uint32_t val) {
|
| }
|
| }
|
|
|
| -uint16_t WasmFunctionBuilder::AddParam(LocalType type) {
|
| - return AddVar(type, true);
|
| -}
|
| -
|
| -uint16_t WasmFunctionBuilder::AddLocal(LocalType type) {
|
| - return AddVar(type, false);
|
| +void WasmFunctionBuilder::SetSignature(FunctionSig* sig) {
|
| + DCHECK(!locals_.has_sig());
|
| + locals_.set_sig(sig);
|
| }
|
|
|
| -uint16_t WasmFunctionBuilder::AddVar(LocalType type, bool param) {
|
| - locals_.push_back({param, type});
|
| - return static_cast<uint16_t>(locals_.size() - 1);
|
| -}
|
| -
|
| -void WasmFunctionBuilder::ReturnType(LocalType type) { return_type_ = type; }
|
| -
|
| -void WasmFunctionBuilder::EmitCode(const byte* code, uint32_t code_size) {
|
| - EmitCode(code, code_size, nullptr, 0);
|
| +uint32_t WasmFunctionBuilder::AddLocal(LocalType type) {
|
| + DCHECK(locals_.has_sig());
|
| + return locals_.AddLocals(1, type);
|
| }
|
|
|
| void WasmFunctionBuilder::EmitGetLocal(uint32_t local_index) {
|
| - local_indices_.push_back(static_cast<uint32_t>(body_.size() + 1));
|
| EmitWithVarInt(kExprGetLocal, local_index);
|
| }
|
|
|
| void WasmFunctionBuilder::EmitSetLocal(uint32_t local_index) {
|
| - local_indices_.push_back(static_cast<uint32_t>(body_.size() + 1));
|
| EmitWithVarInt(kExprSetLocal, local_index);
|
| }
|
|
|
| -void WasmFunctionBuilder::EmitCode(const byte* code, uint32_t code_size,
|
| - const uint32_t* local_indices,
|
| - uint32_t indices_size) {
|
| - size_t size = body_.size();
|
| +void WasmFunctionBuilder::EmitCode(const byte* code, uint32_t code_size) {
|
| for (size_t i = 0; i < code_size; i++) {
|
| body_.push_back(code[i]);
|
| }
|
| - for (size_t i = 0; i < indices_size; i++) {
|
| - local_indices_.push_back(local_indices[i] + static_cast<uint32_t>(size));
|
| - }
|
| }
|
|
|
| void WasmFunctionBuilder::Emit(WasmOpcode opcode) {
|
| @@ -190,35 +163,6 @@ void WasmFunctionBuilder::EmitI32Const(int32_t value) {
|
| }
|
| }
|
|
|
| -uint32_t WasmFunctionBuilder::EmitEditableVarIntImmediate() {
|
| - // Guess that the immediate will be 1 byte. If it is more, we'll have to
|
| - // shift everything down.
|
| - body_.push_back(0);
|
| - return static_cast<uint32_t>(body_.size()) - 1;
|
| -}
|
| -
|
| -void WasmFunctionBuilder::EditVarIntImmediate(uint32_t offset,
|
| - const uint32_t immediate) {
|
| - uint32_t immediate_size =
|
| - static_cast<uint32_t>(LEBHelper::sizeof_u32v(immediate));
|
| - // In EmitEditableVarIntImmediate, we guessed that we'd only need one byte.
|
| - // If we need more, shift everything down to make room for the larger
|
| - // immediate.
|
| - if (immediate_size > 1) {
|
| - uint32_t diff = immediate_size - 1;
|
| - body_.insert(body_.begin() + offset, diff, 0);
|
| -
|
| - for (size_t i = 0; i < local_indices_.size(); ++i) {
|
| - if (local_indices_[i] >= offset) {
|
| - local_indices_[i] += diff;
|
| - }
|
| - }
|
| - }
|
| - DCHECK(offset + immediate_size <= body_.size());
|
| - byte* p = &body_[offset];
|
| - v8::internal::wasm::EmitVarInt(&p, immediate);
|
| -}
|
| -
|
| void WasmFunctionBuilder::Exported(uint8_t flag) { exported_ = flag; }
|
|
|
| void WasmFunctionBuilder::SetName(const char* name, int name_length) {
|
| @@ -233,102 +177,17 @@ void WasmFunctionBuilder::SetName(const char* name, int name_length) {
|
| WasmFunctionEncoder* WasmFunctionBuilder::Build(Zone* zone,
|
| WasmModuleBuilder* mb) const {
|
| WasmFunctionEncoder* e =
|
| - 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) {
|
| - // TODO(titzer): iterate over local indexes, not the bytes.
|
| - const byte* start = &body_[0];
|
| - size_t local_index = 0;
|
| - for (size_t i = 0; i < body_.size();) {
|
| - if (local_index < local_indices_.size() &&
|
| - i == local_indices_[local_index]) {
|
| - // Read the old index.
|
| - uint32_t index = 0;
|
| - uint8_t b = 0;
|
| - uint32_t shift = 0;
|
| - while ((b = start[i++]) >= 0x80) {
|
| - index |= (b & 0x7F) << shift;
|
| - shift += 7;
|
| - }
|
| - index |= b << shift;
|
| -
|
| - // Write the new index.
|
| - uint16_t new_index = var_index[index];
|
| - while (new_index >= 0x80) {
|
| - e->body_.push_back(new_index | 0x80);
|
| - new_index >>= 7;
|
| - }
|
| - e->body_.push_back(new_index);
|
| -
|
| - local_index++;
|
| - } else {
|
| - e->body_.push_back(*(start + i));
|
| - i++;
|
| - }
|
| - }
|
| - }
|
| - FunctionSig::Builder sig(zone, return_type_ == kAstStmt ? 0 : 1,
|
| - e->params_.size());
|
| - if (return_type_ != kAstStmt) {
|
| - sig.AddReturn(static_cast<LocalType>(return_type_));
|
| - }
|
| - for (size_t i = 0; i < e->params_.size(); i++) {
|
| - sig.AddParam(static_cast<LocalType>(e->params_[i]));
|
| - }
|
| - e->signature_index_ = mb->AddSignature(sig.Build());
|
| + new (zone) WasmFunctionEncoder(zone, locals_, exported_);
|
| + // TODO(titzer): lame memcpy here.
|
| + e->body_.insert(e->body_.begin(), body_.begin(), body_.end());
|
| + e->signature_index_ = mb->AddSignature(locals_.get_sig());
|
| e->name_.insert(e->name_.begin(), name_.begin(), name_.end());
|
| return e;
|
| }
|
|
|
| -void WasmFunctionBuilder::IndexVars(WasmFunctionEncoder* e,
|
| - uint16_t* var_index) const {
|
| - uint16_t param = 0;
|
| - uint16_t i32 = 0;
|
| - uint16_t i64 = 0;
|
| - uint16_t f32 = 0;
|
| - uint16_t f64 = 0;
|
| - for (size_t i = 0; i < locals_.size(); i++) {
|
| - if (locals_.at(i).param_) {
|
| - param++;
|
| - } else if (locals_.at(i).type_ == kAstI32) {
|
| - i32++;
|
| - } else if (locals_.at(i).type_ == kAstI64) {
|
| - i64++;
|
| - } else if (locals_.at(i).type_ == kAstF32) {
|
| - f32++;
|
| - } else if (locals_.at(i).type_ == kAstF64) {
|
| - f64++;
|
| - }
|
| - }
|
| - e->local_i32_count_ = i32;
|
| - e->local_i64_count_ = i64;
|
| - e->local_f32_count_ = f32;
|
| - e->local_f64_count_ = f64;
|
| - f64 = param + i32 + i64 + f32;
|
| - f32 = param + i32 + i64;
|
| - i64 = param + i32;
|
| - i32 = param;
|
| - param = 0;
|
| - for (size_t i = 0; i < locals_.size(); i++) {
|
| - if (locals_.at(i).param_) {
|
| - e->params_.push_back(locals_.at(i).type_);
|
| - var_index[i] = param++;
|
| - } else if (locals_.at(i).type_ == kAstI32) {
|
| - var_index[i] = i32++;
|
| - } else if (locals_.at(i).type_ == kAstI64) {
|
| - var_index[i] = i64++;
|
| - } else if (locals_.at(i).type_ == kAstF32) {
|
| - var_index[i] = f32++;
|
| - } else if (locals_.at(i).type_ == kAstF64) {
|
| - var_index[i] = f64++;
|
| - }
|
| - }
|
| -}
|
| -
|
| -WasmFunctionEncoder::WasmFunctionEncoder(Zone* zone, LocalType return_type,
|
| +WasmFunctionEncoder::WasmFunctionEncoder(Zone* zone, LocalDeclEncoder locals,
|
| bool exported)
|
| - : params_(zone), exported_(exported), body_(zone), name_(zone) {}
|
| + : locals_(locals), exported_(exported), body_(zone), name_(zone) {}
|
|
|
| uint32_t WasmFunctionEncoder::HeaderSize() const {
|
| uint32_t size = 3;
|
| @@ -342,14 +201,7 @@ uint32_t WasmFunctionEncoder::HeaderSize() const {
|
| }
|
|
|
| uint32_t WasmFunctionEncoder::BodySize(void) const {
|
| - // 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);
|
| -
|
| - return static_cast<uint32_t>(body_.size() + local_decl.Size());
|
| + return static_cast<uint32_t>(body_.size() + locals_.Size());
|
| }
|
|
|
| uint32_t WasmFunctionEncoder::NameSize() const {
|
| @@ -371,15 +223,8 @@ void WasmFunctionEncoder::Serialize(byte* buffer, byte** header,
|
| }
|
| }
|
|
|
| - // 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);
|
| + EmitUint16(header, static_cast<uint16_t>(body_.size() + locals_.Size()));
|
| + (*header) += locals_.Emit(*header);
|
| if (body_.size() > 0) {
|
| std::memcpy(*header, &body_[0], body_.size());
|
| (*header) += body_.size();
|
| @@ -462,14 +307,14 @@ uint32_t WasmModuleBuilder::AddSignature(FunctionSig* sig) {
|
| if (pos != signature_map_.end()) {
|
| return pos->second;
|
| } else {
|
| - uint16_t index = static_cast<uint16_t>(signatures_.size());
|
| + uint32_t index = static_cast<uint32_t>(signatures_.size());
|
| signature_map_[sig] = index;
|
| signatures_.push_back(sig);
|
| return index;
|
| }
|
| }
|
|
|
| -void WasmModuleBuilder::AddIndirectFunction(uint16_t index) {
|
| +void WasmModuleBuilder::AddIndirectFunction(uint32_t index) {
|
| indirect_functions_.push_back(index);
|
| }
|
|
|
| @@ -479,7 +324,7 @@ uint32_t WasmModuleBuilder::AddImport(const char* name, int name_length,
|
| return static_cast<uint32_t>(imports_.size() - 1);
|
| }
|
|
|
| -void WasmModuleBuilder::MarkStartFunction(uint16_t index) {
|
| +void WasmModuleBuilder::MarkStartFunction(uint32_t index) {
|
| start_function_index_ = index;
|
| }
|
|
|
|
|