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