| 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/zone-containers.h" | 9 #include "src/zone/zone-containers.h" |
| 10 | 10 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 if (FLAG_trace_wasm_encoder) PrintF(__VA_ARGS__); \ | 23 if (FLAG_trace_wasm_encoder) PrintF(__VA_ARGS__); \ |
| 24 } while (false) | 24 } while (false) |
| 25 #else | 25 #else |
| 26 #define TRACE(...) | 26 #define TRACE(...) |
| 27 #endif | 27 #endif |
| 28 | 28 |
| 29 namespace v8 { | 29 namespace v8 { |
| 30 namespace internal { | 30 namespace internal { |
| 31 namespace wasm { | 31 namespace wasm { |
| 32 | 32 |
| 33 // Emit a section code and the size as a padded varint that can be patched | 33 // Emit a section name and the size as a padded varint that can be patched |
| 34 // later. | 34 // later. |
| 35 size_t EmitSection(WasmSectionCode code, ZoneBuffer& buffer) { | 35 size_t EmitSection(WasmSection::Code code, ZoneBuffer& buffer) { |
| 36 // Emit the section code. | 36 // Emit the section name. |
| 37 buffer.write_u8(code); | 37 const char* name = WasmSection::getName(code); |
| 38 TRACE("emit section: %s\n", name); |
| 39 size_t length = WasmSection::getNameLength(code); |
| 40 buffer.write_size(length); // Section name string size. |
| 41 buffer.write(reinterpret_cast<const byte*>(name), length); |
| 38 | 42 |
| 39 // Emit a placeholder for the length. | 43 // Emit a placeholder for the length. |
| 40 return buffer.reserve_u32v(); | 44 return buffer.reserve_u32v(); |
| 41 } | 45 } |
| 42 | 46 |
| 43 // Patch the size of a section after it's finished. | 47 // Patch the size of a section after it's finished. |
| 44 void FixupSection(ZoneBuffer& buffer, size_t start) { | 48 void FixupSection(ZoneBuffer& buffer, size_t start) { |
| 45 buffer.patch_u32v(start, static_cast<uint32_t>(buffer.offset() - start - | 49 buffer.patch_u32v(start, static_cast<uint32_t>(buffer.offset() - start - |
| 46 kPaddedVarInt32Size)); | 50 kPaddedVarInt32Size)); |
| 47 } | 51 } |
| 48 | 52 |
| 49 WasmFunctionBuilder::WasmFunctionBuilder(WasmModuleBuilder* builder) | 53 WasmFunctionBuilder::WasmFunctionBuilder(WasmModuleBuilder* builder) |
| 50 : builder_(builder), | 54 : builder_(builder), |
| 51 locals_(builder->zone()), | 55 locals_(builder->zone()), |
| 52 signature_index_(0), | 56 signature_index_(0), |
| 53 exported_(0), | 57 exported_(0), |
| 54 func_index_(static_cast<uint32_t>(builder->imports_.size() + | |
| 55 builder->functions_.size())), | |
| 56 body_(builder->zone()), | 58 body_(builder->zone()), |
| 57 name_(builder->zone()), | 59 name_(builder->zone()), |
| 58 i32_temps_(builder->zone()), | 60 i32_temps_(builder->zone()), |
| 59 i64_temps_(builder->zone()), | 61 i64_temps_(builder->zone()), |
| 60 f32_temps_(builder->zone()), | 62 f32_temps_(builder->zone()), |
| 61 f64_temps_(builder->zone()) {} | 63 f64_temps_(builder->zone()) {} |
| 62 | 64 |
| 63 void WasmFunctionBuilder::EmitVarInt(uint32_t val) { | 65 void WasmFunctionBuilder::EmitVarInt(uint32_t val) { |
| 64 byte buffer[8]; | 66 byte buffer[8]; |
| 65 byte* ptr = buffer; | 67 byte* ptr = buffer; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 81 } | 83 } |
| 82 | 84 |
| 83 void WasmFunctionBuilder::EmitGetLocal(uint32_t local_index) { | 85 void WasmFunctionBuilder::EmitGetLocal(uint32_t local_index) { |
| 84 EmitWithVarInt(kExprGetLocal, local_index); | 86 EmitWithVarInt(kExprGetLocal, local_index); |
| 85 } | 87 } |
| 86 | 88 |
| 87 void WasmFunctionBuilder::EmitSetLocal(uint32_t local_index) { | 89 void WasmFunctionBuilder::EmitSetLocal(uint32_t local_index) { |
| 88 EmitWithVarInt(kExprSetLocal, local_index); | 90 EmitWithVarInt(kExprSetLocal, local_index); |
| 89 } | 91 } |
| 90 | 92 |
| 91 void WasmFunctionBuilder::EmitTeeLocal(uint32_t local_index) { | |
| 92 EmitWithVarInt(kExprTeeLocal, local_index); | |
| 93 } | |
| 94 | |
| 95 void WasmFunctionBuilder::EmitCode(const byte* code, uint32_t code_size) { | 93 void WasmFunctionBuilder::EmitCode(const byte* code, uint32_t code_size) { |
| 96 for (size_t i = 0; i < code_size; ++i) { | 94 for (size_t i = 0; i < code_size; ++i) { |
| 97 body_.push_back(code[i]); | 95 body_.push_back(code[i]); |
| 98 } | 96 } |
| 99 } | 97 } |
| 100 | 98 |
| 101 void WasmFunctionBuilder::Emit(WasmOpcode opcode) { | 99 void WasmFunctionBuilder::Emit(WasmOpcode opcode) { |
| 102 body_.push_back(static_cast<byte>(opcode)); | 100 body_.push_back(static_cast<byte>(opcode)); |
| 103 } | 101 } |
| 104 | 102 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 for (int i = 0; i < name_length; ++i) { | 136 for (int i = 0; i < name_length; ++i) { |
| 139 name_.push_back(*(name + i)); | 137 name_.push_back(*(name + i)); |
| 140 } | 138 } |
| 141 } | 139 } |
| 142 } | 140 } |
| 143 | 141 |
| 144 void WasmFunctionBuilder::WriteSignature(ZoneBuffer& buffer) const { | 142 void WasmFunctionBuilder::WriteSignature(ZoneBuffer& buffer) const { |
| 145 buffer.write_u32v(signature_index_); | 143 buffer.write_u32v(signature_index_); |
| 146 } | 144 } |
| 147 | 145 |
| 148 void WasmFunctionBuilder::WriteExport(ZoneBuffer& buffer) const { | 146 void WasmFunctionBuilder::WriteExport(ZoneBuffer& buffer, |
| 147 uint32_t func_index) const { |
| 149 if (exported_) { | 148 if (exported_) { |
| 149 buffer.write_u32v(func_index); |
| 150 buffer.write_size(name_.size()); | 150 buffer.write_size(name_.size()); |
| 151 if (name_.size() > 0) { | 151 if (name_.size() > 0) { |
| 152 buffer.write(reinterpret_cast<const byte*>(&name_[0]), name_.size()); | 152 buffer.write(reinterpret_cast<const byte*>(&name_[0]), name_.size()); |
| 153 } | 153 } |
| 154 buffer.write_u8(kExternalFunction); | |
| 155 buffer.write_u32v(func_index_); | |
| 156 } | 154 } |
| 157 } | 155 } |
| 158 | 156 |
| 159 void WasmFunctionBuilder::WriteBody(ZoneBuffer& buffer) const { | 157 void WasmFunctionBuilder::WriteBody(ZoneBuffer& buffer) const { |
| 160 size_t locals_size = locals_.Size(); | 158 size_t locals_size = locals_.Size(); |
| 161 buffer.write_size(locals_size + body_.size()); | 159 buffer.write_size(locals_size + body_.size()); |
| 162 buffer.EnsureSpace(locals_size); | 160 buffer.EnsureSpace(locals_size); |
| 163 byte** ptr = buffer.pos_ptr(); | 161 byte** ptr = buffer.pos_ptr(); |
| 164 locals_.Emit(*ptr); | 162 locals_.Emit(*ptr); |
| 165 (*ptr) += locals_size; // UGLY: manual bump of position pointer | 163 (*ptr) += locals_size; // UGLY: manual bump of position pointer |
| 166 if (body_.size() > 0) { | 164 if (body_.size() > 0) { |
| 167 buffer.write(&body_[0], body_.size()); | 165 buffer.write(&body_[0], body_.size()); |
| 168 } | 166 } |
| 169 } | 167 } |
| 170 | 168 |
| 171 WasmDataSegmentEncoder::WasmDataSegmentEncoder(Zone* zone, const byte* data, | 169 WasmDataSegmentEncoder::WasmDataSegmentEncoder(Zone* zone, const byte* data, |
| 172 uint32_t size, uint32_t dest) | 170 uint32_t size, uint32_t dest) |
| 173 : data_(zone), dest_(dest) { | 171 : data_(zone), dest_(dest) { |
| 174 for (size_t i = 0; i < size; ++i) { | 172 for (size_t i = 0; i < size; ++i) { |
| 175 data_.push_back(data[i]); | 173 data_.push_back(data[i]); |
| 176 } | 174 } |
| 177 } | 175 } |
| 178 | 176 |
| 179 void WasmDataSegmentEncoder::Write(ZoneBuffer& buffer) const { | 177 void WasmDataSegmentEncoder::Write(ZoneBuffer& buffer) const { |
| 180 buffer.write_u8(0); // linear memory zero | |
| 181 buffer.write_u8(kExprI32Const); | |
| 182 buffer.write_u32v(dest_); | 178 buffer.write_u32v(dest_); |
| 183 buffer.write_u8(kExprEnd); | |
| 184 buffer.write_u32v(static_cast<uint32_t>(data_.size())); | 179 buffer.write_u32v(static_cast<uint32_t>(data_.size())); |
| 185 buffer.write(&data_[0], data_.size()); | 180 buffer.write(&data_[0], data_.size()); |
| 186 } | 181 } |
| 187 | 182 |
| 188 WasmModuleBuilder::WasmModuleBuilder(Zone* zone) | 183 WasmModuleBuilder::WasmModuleBuilder(Zone* zone) |
| 189 : zone_(zone), | 184 : zone_(zone), |
| 190 signatures_(zone), | 185 signatures_(zone), |
| 191 imports_(zone), | 186 imports_(zone), |
| 192 functions_(zone), | 187 functions_(zone), |
| 193 data_segments_(zone), | 188 data_segments_(zone), |
| 194 indirect_functions_(zone), | 189 indirect_functions_(zone), |
| 195 globals_(zone), | 190 globals_(zone), |
| 196 signature_map_(zone), | 191 signature_map_(zone), |
| 197 start_function_index_(-1) {} | 192 start_function_index_(-1) {} |
| 198 | 193 |
| 199 WasmFunctionBuilder* WasmModuleBuilder::AddFunction(FunctionSig* sig) { | 194 uint32_t WasmModuleBuilder::AddFunction() { |
| 200 functions_.push_back(new (zone_) WasmFunctionBuilder(this)); | 195 functions_.push_back(new (zone_) WasmFunctionBuilder(this)); |
| 201 // Add the signature if one was provided here. | 196 return static_cast<uint32_t>(functions_.size() - 1); |
| 202 if (sig) functions_.back()->SetSignature(sig); | 197 } |
| 203 return functions_.back(); | 198 |
| 199 WasmFunctionBuilder* WasmModuleBuilder::FunctionAt(size_t index) { |
| 200 if (functions_.size() > index) { |
| 201 return functions_.at(index); |
| 202 } else { |
| 203 return nullptr; |
| 204 } |
| 204 } | 205 } |
| 205 | 206 |
| 206 void WasmModuleBuilder::AddDataSegment(WasmDataSegmentEncoder* data) { | 207 void WasmModuleBuilder::AddDataSegment(WasmDataSegmentEncoder* data) { |
| 207 data_segments_.push_back(data); | 208 data_segments_.push_back(data); |
| 208 } | 209 } |
| 209 | 210 |
| 210 bool WasmModuleBuilder::CompareFunctionSigs::operator()(FunctionSig* a, | 211 bool WasmModuleBuilder::CompareFunctionSigs::operator()(FunctionSig* a, |
| 211 FunctionSig* b) const { | 212 FunctionSig* b) const { |
| 212 if (a->return_count() < b->return_count()) return true; | 213 if (a->return_count() < b->return_count()) return true; |
| 213 if (a->return_count() > b->return_count()) return false; | 214 if (a->return_count() > b->return_count()) return false; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 235 return index; | 236 return index; |
| 236 } | 237 } |
| 237 } | 238 } |
| 238 | 239 |
| 239 void WasmModuleBuilder::AddIndirectFunction(uint32_t index) { | 240 void WasmModuleBuilder::AddIndirectFunction(uint32_t index) { |
| 240 indirect_functions_.push_back(index); | 241 indirect_functions_.push_back(index); |
| 241 } | 242 } |
| 242 | 243 |
| 243 uint32_t WasmModuleBuilder::AddImport(const char* name, int name_length, | 244 uint32_t WasmModuleBuilder::AddImport(const char* name, int name_length, |
| 244 FunctionSig* sig) { | 245 FunctionSig* sig) { |
| 245 DCHECK_EQ(0, functions_.size()); // imports must be added before functions! | |
| 246 imports_.push_back({AddSignature(sig), name, name_length}); | 246 imports_.push_back({AddSignature(sig), name, name_length}); |
| 247 return static_cast<uint32_t>(imports_.size() - 1); | 247 return static_cast<uint32_t>(imports_.size() - 1); |
| 248 } | 248 } |
| 249 | 249 |
| 250 void WasmModuleBuilder::MarkStartFunction(WasmFunctionBuilder* function) { | 250 void WasmModuleBuilder::MarkStartFunction(uint32_t index) { |
| 251 start_function_index_ = function->func_index(); | 251 start_function_index_ = index; |
| 252 } | 252 } |
| 253 | 253 |
| 254 uint32_t WasmModuleBuilder::AddGlobal(LocalType type, bool exported, | 254 uint32_t WasmModuleBuilder::AddGlobal(LocalType type, bool exported) { |
| 255 bool mutability) { | 255 globals_.push_back(std::make_pair(type, exported)); |
| 256 globals_.push_back(std::make_tuple(type, exported, mutability)); | |
| 257 return static_cast<uint32_t>(globals_.size() - 1); | 256 return static_cast<uint32_t>(globals_.size() - 1); |
| 258 } | 257 } |
| 259 | 258 |
| 260 void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { | 259 void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { |
| 261 uint32_t exports = 0; | 260 uint32_t exports = 0; |
| 262 | 261 |
| 263 // == Emit magic ============================================================= | 262 // == Emit magic ============================================================= |
| 264 TRACE("emit magic\n"); | 263 TRACE("emit magic\n"); |
| 265 buffer.write_u32(kWasmMagic); | 264 buffer.write_u32(kWasmMagic); |
| 266 buffer.write_u32(kWasmVersion); | 265 buffer.write_u32(kWasmVersion); |
| 267 | 266 |
| 268 // == Emit signatures ======================================================== | 267 // == Emit signatures ======================================================== |
| 269 if (signatures_.size() > 0) { | 268 if (signatures_.size() > 0) { |
| 270 size_t start = EmitSection(kTypeSectionCode, buffer); | 269 size_t start = EmitSection(WasmSection::Code::Signatures, buffer); |
| 271 buffer.write_size(signatures_.size()); | 270 buffer.write_size(signatures_.size()); |
| 272 | 271 |
| 273 for (FunctionSig* sig : signatures_) { | 272 for (FunctionSig* sig : signatures_) { |
| 274 buffer.write_u8(kWasmFunctionTypeForm); | 273 buffer.write_u8(kWasmFunctionTypeForm); |
| 275 buffer.write_size(sig->parameter_count()); | 274 buffer.write_size(sig->parameter_count()); |
| 276 for (size_t j = 0; j < sig->parameter_count(); j++) { | 275 for (size_t j = 0; j < sig->parameter_count(); j++) { |
| 277 buffer.write_u8(WasmOpcodes::LocalTypeCodeFor(sig->GetParam(j))); | 276 buffer.write_u8(WasmOpcodes::LocalTypeCodeFor(sig->GetParam(j))); |
| 278 } | 277 } |
| 279 buffer.write_size(sig->return_count()); | 278 buffer.write_size(sig->return_count()); |
| 280 for (size_t j = 0; j < sig->return_count(); j++) { | 279 for (size_t j = 0; j < sig->return_count(); j++) { |
| 281 buffer.write_u8(WasmOpcodes::LocalTypeCodeFor(sig->GetReturn(j))); | 280 buffer.write_u8(WasmOpcodes::LocalTypeCodeFor(sig->GetReturn(j))); |
| 282 } | 281 } |
| 283 } | 282 } |
| 284 FixupSection(buffer, start); | 283 FixupSection(buffer, start); |
| 285 } | 284 } |
| 286 | 285 |
| 286 // == Emit globals =========================================================== |
| 287 if (globals_.size() > 0) { |
| 288 size_t start = EmitSection(WasmSection::Code::Globals, buffer); |
| 289 buffer.write_size(globals_.size()); |
| 290 |
| 291 for (auto global : globals_) { |
| 292 buffer.write_u32v(0); // Length of the global name. |
| 293 buffer.write_u8(WasmOpcodes::LocalTypeCodeFor(global.first)); |
| 294 buffer.write_u8(global.second); |
| 295 } |
| 296 FixupSection(buffer, start); |
| 297 } |
| 298 |
| 287 // == Emit imports =========================================================== | 299 // == Emit imports =========================================================== |
| 288 if (imports_.size() > 0) { | 300 if (imports_.size() > 0) { |
| 289 size_t start = EmitSection(kImportSectionCode, buffer); | 301 size_t start = EmitSection(WasmSection::Code::ImportTable, buffer); |
| 290 buffer.write_size(imports_.size()); | 302 buffer.write_size(imports_.size()); |
| 291 for (auto import : imports_) { | 303 for (auto import : imports_) { |
| 292 buffer.write_u32v(import.name_length); // module name length | 304 buffer.write_u32v(import.sig_index); |
| 293 buffer.write(reinterpret_cast<const byte*>(import.name), // module name | 305 buffer.write_u32v(import.name_length); |
| 306 buffer.write(reinterpret_cast<const byte*>(import.name), |
| 294 import.name_length); | 307 import.name_length); |
| 295 buffer.write_u32v(0); // field name length | 308 buffer.write_u32v(0); |
| 296 buffer.write_u8(kExternalFunction); | |
| 297 buffer.write_u32v(import.sig_index); | |
| 298 } | 309 } |
| 299 FixupSection(buffer, start); | 310 FixupSection(buffer, start); |
| 300 } | 311 } |
| 301 | 312 |
| 302 // == Emit function signatures =============================================== | 313 // == Emit function signatures =============================================== |
| 303 bool has_names = false; | |
| 304 if (functions_.size() > 0) { | 314 if (functions_.size() > 0) { |
| 305 size_t start = EmitSection(kFunctionSectionCode, buffer); | 315 size_t start = EmitSection(WasmSection::Code::FunctionSignatures, buffer); |
| 306 buffer.write_size(functions_.size()); | 316 buffer.write_size(functions_.size()); |
| 307 for (auto function : functions_) { | 317 for (auto function : functions_) { |
| 308 function->WriteSignature(buffer); | 318 function->WriteSignature(buffer); |
| 309 if (function->exported()) exports++; | 319 if (function->exported()) exports++; |
| 310 if (function->name_.size() > 0) has_names = true; | |
| 311 } | 320 } |
| 312 FixupSection(buffer, start); | 321 FixupSection(buffer, start); |
| 313 } | 322 } |
| 314 | 323 |
| 315 // == emit function table ==================================================== | 324 // == emit function table ==================================================== |
| 316 if (indirect_functions_.size() > 0) { | 325 if (indirect_functions_.size() > 0) { |
| 317 size_t start = EmitSection(kTableSectionCode, buffer); | 326 size_t start = EmitSection(WasmSection::Code::FunctionTable, buffer); |
| 318 buffer.write_u8(1); // table count | |
| 319 buffer.write_u8(kWasmAnyFunctionTypeForm); | |
| 320 buffer.write_u8(kResizableMaximumFlag); | |
| 321 buffer.write_size(indirect_functions_.size()); | 327 buffer.write_size(indirect_functions_.size()); |
| 322 buffer.write_size(indirect_functions_.size()); | 328 |
| 329 for (auto index : indirect_functions_) { |
| 330 buffer.write_u32v(index); |
| 331 } |
| 323 FixupSection(buffer, start); | 332 FixupSection(buffer, start); |
| 324 } | 333 } |
| 325 | 334 |
| 326 // == emit memory declaration ================================================ | 335 // == emit memory declaration ================================================ |
| 327 { | 336 { |
| 328 size_t start = EmitSection(kMemorySectionCode, buffer); | 337 size_t start = EmitSection(WasmSection::Code::Memory, buffer); |
| 329 buffer.write_u8(1); // memory count | |
| 330 buffer.write_u32v(kResizableMaximumFlag); | |
| 331 buffer.write_u32v(16); // min memory size | 338 buffer.write_u32v(16); // min memory size |
| 332 buffer.write_u32v(16); // max memory size | 339 buffer.write_u32v(16); // max memory size |
| 333 FixupSection(buffer, start); | 340 buffer.write_u8(0); // memory export |
| 334 } | 341 static_assert(kDeclMemorySize == 3, "memory size must match emit above"); |
| 335 | |
| 336 // == Emit globals =========================================================== | |
| 337 if (globals_.size() > 0) { | |
| 338 size_t start = EmitSection(kGlobalSectionCode, buffer); | |
| 339 buffer.write_size(globals_.size()); | |
| 340 | |
| 341 for (auto global : globals_) { | |
| 342 static const int kLocalTypeIndex = 0; | |
| 343 static const int kMutabilityIndex = 2; | |
| 344 buffer.write_u8( | |
| 345 WasmOpcodes::LocalTypeCodeFor(std::get<kLocalTypeIndex>(global))); | |
| 346 buffer.write_u8(std::get<kMutabilityIndex>(global)); | |
| 347 switch (std::get<kLocalTypeIndex>(global)) { | |
| 348 case kAstI32: { | |
| 349 static const byte code[] = {WASM_I32V_1(0)}; | |
| 350 buffer.write(code, sizeof(code)); | |
| 351 break; | |
| 352 } | |
| 353 case kAstF32: { | |
| 354 static const byte code[] = {WASM_F32(0)}; | |
| 355 buffer.write(code, sizeof(code)); | |
| 356 break; | |
| 357 } | |
| 358 case kAstI64: { | |
| 359 static const byte code[] = {WASM_I64V_1(0)}; | |
| 360 buffer.write(code, sizeof(code)); | |
| 361 break; | |
| 362 } | |
| 363 case kAstF64: { | |
| 364 static const byte code[] = {WASM_F64(0.0)}; | |
| 365 buffer.write(code, sizeof(code)); | |
| 366 break; | |
| 367 } | |
| 368 default: | |
| 369 UNREACHABLE(); | |
| 370 } | |
| 371 buffer.write_u8(kExprEnd); | |
| 372 } | |
| 373 FixupSection(buffer, start); | 342 FixupSection(buffer, start); |
| 374 } | 343 } |
| 375 | 344 |
| 376 // == emit exports =========================================================== | 345 // == emit exports =========================================================== |
| 377 if (exports > 0) { | 346 if (exports > 0) { |
| 378 size_t start = EmitSection(kExportSectionCode, buffer); | 347 size_t start = EmitSection(WasmSection::Code::ExportTable, buffer); |
| 379 buffer.write_u32v(exports); | 348 buffer.write_u32v(exports); |
| 380 for (auto function : functions_) function->WriteExport(buffer); | 349 uint32_t index = 0; |
| 350 for (auto function : functions_) { |
| 351 function->WriteExport(buffer, index++); |
| 352 } |
| 381 FixupSection(buffer, start); | 353 FixupSection(buffer, start); |
| 382 } | 354 } |
| 383 | 355 |
| 384 // == emit start function index ============================================== | 356 // == emit start function index ============================================== |
| 385 if (start_function_index_ >= 0) { | 357 if (start_function_index_ >= 0) { |
| 386 size_t start = EmitSection(kStartSectionCode, buffer); | 358 size_t start = EmitSection(WasmSection::Code::StartFunction, buffer); |
| 387 buffer.write_u32v(start_function_index_); | 359 buffer.write_u32v(start_function_index_); |
| 388 FixupSection(buffer, start); | 360 FixupSection(buffer, start); |
| 389 } | 361 } |
| 390 | 362 |
| 391 // == emit function table elements =========================================== | |
| 392 if (indirect_functions_.size() > 0) { | |
| 393 size_t start = EmitSection(kElementSectionCode, buffer); | |
| 394 buffer.write_u8(1); // count of entries | |
| 395 buffer.write_u8(0); // table index | |
| 396 buffer.write_u8(kExprI32Const); // offset | |
| 397 buffer.write_u32v(0); | |
| 398 buffer.write_u8(kExprEnd); | |
| 399 buffer.write_size(indirect_functions_.size()); // element count | |
| 400 | |
| 401 for (auto index : indirect_functions_) { | |
| 402 buffer.write_u32v(index); | |
| 403 } | |
| 404 | |
| 405 FixupSection(buffer, start); | |
| 406 } | |
| 407 | |
| 408 // == emit code ============================================================== | 363 // == emit code ============================================================== |
| 409 if (functions_.size() > 0) { | 364 if (functions_.size() > 0) { |
| 410 size_t start = EmitSection(kCodeSectionCode, buffer); | 365 size_t start = EmitSection(WasmSection::Code::FunctionBodies, buffer); |
| 411 buffer.write_size(functions_.size()); | 366 buffer.write_size(functions_.size()); |
| 412 for (auto function : functions_) { | 367 for (auto function : functions_) { |
| 413 function->WriteBody(buffer); | 368 function->WriteBody(buffer); |
| 414 } | 369 } |
| 415 FixupSection(buffer, start); | 370 FixupSection(buffer, start); |
| 416 } | 371 } |
| 417 | 372 |
| 418 // == emit data segments ===================================================== | 373 // == emit data segments ===================================================== |
| 419 if (data_segments_.size() > 0) { | 374 if (data_segments_.size() > 0) { |
| 420 size_t start = EmitSection(kDataSectionCode, buffer); | 375 size_t start = EmitSection(WasmSection::Code::DataSegments, buffer); |
| 421 buffer.write_size(data_segments_.size()); | 376 buffer.write_size(data_segments_.size()); |
| 422 | 377 |
| 423 for (auto segment : data_segments_) { | 378 for (auto segment : data_segments_) { |
| 424 segment->Write(buffer); | 379 segment->Write(buffer); |
| 425 } | 380 } |
| 426 FixupSection(buffer, start); | 381 FixupSection(buffer, start); |
| 427 } | 382 } |
| 428 | |
| 429 // == Emit names ============================================================= | |
| 430 if (has_names) { | |
| 431 // Emit the section code. | |
| 432 buffer.write_u8(kUnknownSectionCode); | |
| 433 // Emit a placeholder for the length. | |
| 434 size_t start = buffer.reserve_u32v(); | |
| 435 // Emit the section string. | |
| 436 buffer.write_size(4); | |
| 437 buffer.write(reinterpret_cast<const byte*>("name"), 4); | |
| 438 // Emit the names. | |
| 439 buffer.write_size(functions_.size()); | |
| 440 for (auto function : functions_) { | |
| 441 buffer.write_size(function->name_.size()); | |
| 442 if (function->name_.size() > 0) { | |
| 443 buffer.write(reinterpret_cast<const byte*>(&function->name_[0]), | |
| 444 function->name_.size()); | |
| 445 } | |
| 446 buffer.write_u8(0); | |
| 447 } | |
| 448 FixupSection(buffer, start); | |
| 449 } | |
| 450 } | 383 } |
| 451 } // namespace wasm | 384 } // namespace wasm |
| 452 } // namespace internal | 385 } // namespace internal |
| 453 } // namespace v8 | 386 } // namespace v8 |
| OLD | NEW |