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 |