| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/signature.h" | 5 #include "src/signature.h" |
| 6 | 6 |
| 7 #include "src/handles.h" | 7 #include "src/handles.h" |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 #include "src/zone-containers.h" | 9 #include "src/zone-containers.h" |
| 10 | 10 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 // Emit a placeholder for the length. | 43 // Emit a placeholder for the length. |
| 44 return buffer.reserve_u32v(); | 44 return buffer.reserve_u32v(); |
| 45 } | 45 } |
| 46 | 46 |
| 47 // Patch the size of a section after it's finished. | 47 // Patch the size of a section after it's finished. |
| 48 void FixupSection(ZoneBuffer& buffer, size_t start) { | 48 void FixupSection(ZoneBuffer& buffer, size_t start) { |
| 49 buffer.patch_u32v(start, static_cast<uint32_t>(buffer.offset() - start - | 49 buffer.patch_u32v(start, static_cast<uint32_t>(buffer.offset() - start - |
| 50 kPaddedVarInt32Size)); | 50 kPaddedVarInt32Size)); |
| 51 } | 51 } |
| 52 | 52 |
| 53 WasmFunctionBuilder::WasmFunctionBuilder(Zone* zone) | 53 WasmFunctionBuilder::WasmFunctionBuilder(WasmModuleBuilder* builder) |
| 54 : locals_(zone), exported_(0), body_(zone), name_(zone) {} | 54 : builder_(builder), |
| 55 locals_(builder->zone()), |
| 56 signature_index_(0), |
| 57 exported_(0), |
| 58 body_(builder->zone()), |
| 59 name_(builder->zone()) {} |
| 55 | 60 |
| 56 void WasmFunctionBuilder::EmitVarInt(uint32_t val) { | 61 void WasmFunctionBuilder::EmitVarInt(uint32_t val) { |
| 57 byte buffer[8]; | 62 byte buffer[8]; |
| 58 byte* ptr = buffer; | 63 byte* ptr = buffer; |
| 59 LEBHelper::write_u32v(&ptr, val); | 64 LEBHelper::write_u32v(&ptr, val); |
| 60 for (byte* p = buffer; p < ptr; p++) { | 65 for (byte* p = buffer; p < ptr; p++) { |
| 61 body_.push_back(*p); | 66 body_.push_back(*p); |
| 62 } | 67 } |
| 63 } | 68 } |
| 64 | 69 |
| 65 void WasmFunctionBuilder::SetSignature(FunctionSig* sig) { | 70 void WasmFunctionBuilder::SetSignature(FunctionSig* sig) { |
| 66 DCHECK(!locals_.has_sig()); | 71 DCHECK(!locals_.has_sig()); |
| 67 locals_.set_sig(sig); | 72 locals_.set_sig(sig); |
| 73 signature_index_ = builder_->AddSignature(sig); |
| 68 } | 74 } |
| 69 | 75 |
| 70 uint32_t WasmFunctionBuilder::AddLocal(LocalType type) { | 76 uint32_t WasmFunctionBuilder::AddLocal(LocalType type) { |
| 71 DCHECK(locals_.has_sig()); | 77 DCHECK(locals_.has_sig()); |
| 72 return locals_.AddLocals(1, type); | 78 return locals_.AddLocals(1, type); |
| 73 } | 79 } |
| 74 | 80 |
| 75 void WasmFunctionBuilder::EmitGetLocal(uint32_t local_index) { | 81 void WasmFunctionBuilder::EmitGetLocal(uint32_t local_index) { |
| 76 EmitWithVarInt(kExprGetLocal, local_index); | 82 EmitWithVarInt(kExprGetLocal, local_index); |
| 77 } | 83 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 void WasmFunctionBuilder::EmitI32Const(int32_t value) { | 117 void WasmFunctionBuilder::EmitI32Const(int32_t value) { |
| 112 // TODO(titzer): variable-length signed and unsigned i32 constants. | 118 // TODO(titzer): variable-length signed and unsigned i32 constants. |
| 113 if (-128 <= value && value <= 127) { | 119 if (-128 <= value && value <= 127) { |
| 114 EmitWithU8(kExprI8Const, static_cast<byte>(value)); | 120 EmitWithU8(kExprI8Const, static_cast<byte>(value)); |
| 115 } else { | 121 } else { |
| 116 byte code[] = {WASM_I32V_5(value)}; | 122 byte code[] = {WASM_I32V_5(value)}; |
| 117 EmitCode(code, sizeof(code)); | 123 EmitCode(code, sizeof(code)); |
| 118 } | 124 } |
| 119 } | 125 } |
| 120 | 126 |
| 121 void WasmFunctionBuilder::Exported(uint8_t flag) { exported_ = flag; } | 127 void WasmFunctionBuilder::SetExported() { exported_ = true; } |
| 122 | 128 |
| 123 void WasmFunctionBuilder::SetName(const char* name, int name_length) { | 129 void WasmFunctionBuilder::SetName(const char* name, int name_length) { |
| 124 name_.clear(); | 130 name_.clear(); |
| 125 if (name_length > 0) { | 131 if (name_length > 0) { |
| 126 for (int i = 0; i < name_length; i++) { | 132 for (int i = 0; i < name_length; i++) { |
| 127 name_.push_back(*(name + i)); | 133 name_.push_back(*(name + i)); |
| 128 } | 134 } |
| 129 } | 135 } |
| 130 } | 136 } |
| 131 | 137 |
| 132 WasmFunctionEncoder* WasmFunctionBuilder::Build(Zone* zone, | 138 void WasmFunctionBuilder::WriteSignature(ZoneBuffer& buffer) const { |
| 133 WasmModuleBuilder* mb) const { | |
| 134 WasmFunctionEncoder* e = | |
| 135 new (zone) WasmFunctionEncoder(zone, locals_, exported_); | |
| 136 // TODO(titzer): lame memcpy here. | |
| 137 e->body_.insert(e->body_.begin(), body_.begin(), body_.end()); | |
| 138 e->signature_index_ = mb->AddSignature(locals_.get_sig()); | |
| 139 e->name_.insert(e->name_.begin(), name_.begin(), name_.end()); | |
| 140 return e; | |
| 141 } | |
| 142 | |
| 143 WasmFunctionEncoder::WasmFunctionEncoder(Zone* zone, LocalDeclEncoder locals, | |
| 144 bool exported) | |
| 145 : locals_(locals), exported_(exported), body_(zone), name_(zone) {} | |
| 146 | |
| 147 void WasmFunctionEncoder::WriteSignature(ZoneBuffer& buffer) const { | |
| 148 buffer.write_u32v(signature_index_); | 139 buffer.write_u32v(signature_index_); |
| 149 } | 140 } |
| 150 | 141 |
| 151 void WasmFunctionEncoder::WriteExport(ZoneBuffer& buffer, | 142 void WasmFunctionBuilder::WriteExport(ZoneBuffer& buffer, |
| 152 uint32_t func_index) const { | 143 uint32_t func_index) const { |
| 153 if (exported_) { | 144 if (exported_) { |
| 154 buffer.write_u32v(func_index); | 145 buffer.write_u32v(func_index); |
| 155 buffer.write_size(name_.size()); | 146 buffer.write_size(name_.size()); |
| 156 if (name_.size() > 0) { | 147 if (name_.size() > 0) { |
| 157 buffer.write(reinterpret_cast<const byte*>(&name_[0]), name_.size()); | 148 buffer.write(reinterpret_cast<const byte*>(&name_[0]), name_.size()); |
| 158 } | 149 } |
| 159 } | 150 } |
| 160 } | 151 } |
| 161 | 152 |
| 162 void WasmFunctionEncoder::WriteBody(ZoneBuffer& buffer) const { | 153 void WasmFunctionBuilder::WriteBody(ZoneBuffer& buffer) const { |
| 163 size_t locals_size = locals_.Size(); | 154 size_t locals_size = locals_.Size(); |
| 164 buffer.write_size(locals_size + body_.size()); | 155 buffer.write_size(locals_size + body_.size()); |
| 165 buffer.EnsureSpace(locals_size); | 156 buffer.EnsureSpace(locals_size); |
| 166 byte** ptr = buffer.pos_ptr(); | 157 byte** ptr = buffer.pos_ptr(); |
| 167 locals_.Emit(*ptr); | 158 locals_.Emit(*ptr); |
| 168 (*ptr) += locals_size; // UGLY: manual bump of position pointer | 159 (*ptr) += locals_size; // UGLY: manual bump of position pointer |
| 169 if (body_.size() > 0) { | 160 if (body_.size() > 0) { |
| 170 buffer.write(&body_[0], body_.size()); | 161 buffer.write(&body_[0], body_.size()); |
| 171 } | 162 } |
| 172 } | 163 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 190 signatures_(zone), | 181 signatures_(zone), |
| 191 imports_(zone), | 182 imports_(zone), |
| 192 functions_(zone), | 183 functions_(zone), |
| 193 data_segments_(zone), | 184 data_segments_(zone), |
| 194 indirect_functions_(zone), | 185 indirect_functions_(zone), |
| 195 globals_(zone), | 186 globals_(zone), |
| 196 signature_map_(zone), | 187 signature_map_(zone), |
| 197 start_function_index_(-1) {} | 188 start_function_index_(-1) {} |
| 198 | 189 |
| 199 uint32_t WasmModuleBuilder::AddFunction() { | 190 uint32_t WasmModuleBuilder::AddFunction() { |
| 200 functions_.push_back(new (zone_) WasmFunctionBuilder(zone_)); | 191 functions_.push_back(new (zone_) WasmFunctionBuilder(this)); |
| 201 return static_cast<uint32_t>(functions_.size() - 1); | 192 return static_cast<uint32_t>(functions_.size() - 1); |
| 202 } | 193 } |
| 203 | 194 |
| 204 WasmFunctionBuilder* WasmModuleBuilder::FunctionAt(size_t index) { | 195 WasmFunctionBuilder* WasmModuleBuilder::FunctionAt(size_t index) { |
| 205 if (functions_.size() > index) { | 196 if (functions_.size() > index) { |
| 206 return functions_.at(index); | 197 return functions_.at(index); |
| 207 } else { | 198 } else { |
| 208 return nullptr; | 199 return nullptr; |
| 209 } | 200 } |
| 210 } | 201 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 uint32_t WasmModuleBuilder::AddImport(const char* name, int name_length, | 240 uint32_t WasmModuleBuilder::AddImport(const char* name, int name_length, |
| 250 FunctionSig* sig) { | 241 FunctionSig* sig) { |
| 251 imports_.push_back({AddSignature(sig), name, name_length}); | 242 imports_.push_back({AddSignature(sig), name, name_length}); |
| 252 return static_cast<uint32_t>(imports_.size() - 1); | 243 return static_cast<uint32_t>(imports_.size() - 1); |
| 253 } | 244 } |
| 254 | 245 |
| 255 void WasmModuleBuilder::MarkStartFunction(uint32_t index) { | 246 void WasmModuleBuilder::MarkStartFunction(uint32_t index) { |
| 256 start_function_index_ = index; | 247 start_function_index_ = index; |
| 257 } | 248 } |
| 258 | 249 |
| 259 WasmModuleWriter* WasmModuleBuilder::Build(Zone* zone) { | |
| 260 WasmModuleWriter* writer = new (zone) WasmModuleWriter(zone); | |
| 261 for (auto import : imports_) { | |
| 262 writer->imports_.push_back(import); | |
| 263 } | |
| 264 for (auto function : functions_) { | |
| 265 writer->functions_.push_back(function->Build(zone, this)); | |
| 266 } | |
| 267 for (auto segment : data_segments_) { | |
| 268 writer->data_segments_.push_back(segment); | |
| 269 } | |
| 270 for (auto sig : signatures_) { | |
| 271 writer->signatures_.push_back(sig); | |
| 272 } | |
| 273 for (auto index : indirect_functions_) { | |
| 274 writer->indirect_functions_.push_back(index); | |
| 275 } | |
| 276 for (auto global : globals_) { | |
| 277 writer->globals_.push_back(global); | |
| 278 } | |
| 279 writer->start_function_index_ = start_function_index_; | |
| 280 return writer; | |
| 281 } | |
| 282 | |
| 283 uint32_t WasmModuleBuilder::AddGlobal(MachineType type, bool exported) { | 250 uint32_t WasmModuleBuilder::AddGlobal(MachineType type, bool exported) { |
| 284 globals_.push_back(std::make_pair(type, exported)); | 251 globals_.push_back(std::make_pair(type, exported)); |
| 285 return static_cast<uint32_t>(globals_.size() - 1); | 252 return static_cast<uint32_t>(globals_.size() - 1); |
| 286 } | 253 } |
| 287 | 254 |
| 288 WasmModuleWriter::WasmModuleWriter(Zone* zone) | 255 void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { |
| 289 : imports_(zone), | |
| 290 functions_(zone), | |
| 291 data_segments_(zone), | |
| 292 signatures_(zone), | |
| 293 indirect_functions_(zone), | |
| 294 globals_(zone) {} | |
| 295 | |
| 296 void WasmModuleWriter::WriteTo(ZoneBuffer& buffer) const { | |
| 297 uint32_t exports = 0; | 256 uint32_t exports = 0; |
| 298 | 257 |
| 299 // == Emit magic ============================================================= | 258 // == Emit magic ============================================================= |
| 300 TRACE("emit magic\n"); | 259 TRACE("emit magic\n"); |
| 301 buffer.write_u32(kWasmMagic); | 260 buffer.write_u32(kWasmMagic); |
| 302 buffer.write_u32(kWasmVersion); | 261 buffer.write_u32(kWasmVersion); |
| 303 | 262 |
| 304 // == Emit signatures ======================================================== | 263 // == Emit signatures ======================================================== |
| 305 if (signatures_.size() > 0) { | 264 if (signatures_.size() > 0) { |
| 306 size_t start = EmitSection(WasmSection::Code::Signatures, buffer); | 265 size_t start = EmitSection(WasmSection::Code::Signatures, buffer); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 | 373 |
| 415 for (auto segment : data_segments_) { | 374 for (auto segment : data_segments_) { |
| 416 segment->Write(buffer); | 375 segment->Write(buffer); |
| 417 } | 376 } |
| 418 FixupSection(buffer, start); | 377 FixupSection(buffer, start); |
| 419 } | 378 } |
| 420 } | 379 } |
| 421 } // namespace wasm | 380 } // namespace wasm |
| 422 } // namespace internal | 381 } // namespace internal |
| 423 } // namespace v8 | 382 } // namespace v8 |
| OLD | NEW |