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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 buffer.write_size(locals_size + body_.size()); | 161 buffer.write_size(locals_size + body_.size()); |
162 buffer.EnsureSpace(locals_size); | 162 buffer.EnsureSpace(locals_size); |
163 byte** ptr = buffer.pos_ptr(); | 163 byte** ptr = buffer.pos_ptr(); |
164 locals_.Emit(*ptr); | 164 locals_.Emit(*ptr); |
165 (*ptr) += locals_size; // UGLY: manual bump of position pointer | 165 (*ptr) += locals_size; // UGLY: manual bump of position pointer |
166 if (body_.size() > 0) { | 166 if (body_.size() > 0) { |
167 buffer.write(&body_[0], body_.size()); | 167 buffer.write(&body_[0], body_.size()); |
168 } | 168 } |
169 } | 169 } |
170 | 170 |
171 WasmDataSegmentEncoder::WasmDataSegmentEncoder(Zone* zone, const byte* data, | |
172 uint32_t size, uint32_t dest) | |
173 : data_(zone), dest_(dest) { | |
174 for (size_t i = 0; i < size; ++i) { | |
175 data_.push_back(data[i]); | |
176 } | |
177 } | |
178 | |
179 void WasmDataSegmentEncoder::Write(ZoneBuffer& buffer) const { | |
180 buffer.write_u8(0); // linear memory zero | |
181 buffer.write_u8(kExprI32Const); | |
182 buffer.write_u32v(dest_); | |
183 buffer.write_u8(kExprEnd); | |
184 buffer.write_u32v(static_cast<uint32_t>(data_.size())); | |
185 buffer.write(&data_[0], data_.size()); | |
186 } | |
187 | |
188 WasmModuleBuilder::WasmModuleBuilder(Zone* zone) | 171 WasmModuleBuilder::WasmModuleBuilder(Zone* zone) |
189 : zone_(zone), | 172 : zone_(zone), |
190 signatures_(zone), | 173 signatures_(zone), |
191 imports_(zone), | 174 imports_(zone), |
192 functions_(zone), | 175 functions_(zone), |
193 data_segments_(zone), | 176 data_segments_(zone), |
194 indirect_functions_(zone), | 177 indirect_functions_(zone), |
195 globals_(zone), | 178 globals_(zone), |
196 signature_map_(zone), | 179 signature_map_(zone), |
197 start_function_index_(-1) {} | 180 start_function_index_(-1) {} |
198 | 181 |
199 WasmFunctionBuilder* WasmModuleBuilder::AddFunction(FunctionSig* sig) { | 182 WasmFunctionBuilder* WasmModuleBuilder::AddFunction(FunctionSig* sig) { |
200 functions_.push_back(new (zone_) WasmFunctionBuilder(this)); | 183 functions_.push_back(new (zone_) WasmFunctionBuilder(this)); |
201 // Add the signature if one was provided here. | 184 // Add the signature if one was provided here. |
202 if (sig) functions_.back()->SetSignature(sig); | 185 if (sig) functions_.back()->SetSignature(sig); |
203 return functions_.back(); | 186 return functions_.back(); |
204 } | 187 } |
205 | 188 |
206 void WasmModuleBuilder::AddDataSegment(WasmDataSegmentEncoder* data) { | 189 void WasmModuleBuilder::AddDataSegment(const byte* data, uint32_t size, |
207 data_segments_.push_back(data); | 190 uint32_t dest) { |
| 191 data_segments_.push_back({ZoneVector<byte>(zone()), dest}); |
| 192 ZoneVector<byte>& vec = data_segments_.back().data; |
| 193 for (uint32_t i = 0; i < size; i++) { |
| 194 vec.push_back(data[i]); |
| 195 } |
208 } | 196 } |
209 | 197 |
210 bool WasmModuleBuilder::CompareFunctionSigs::operator()(FunctionSig* a, | 198 bool WasmModuleBuilder::CompareFunctionSigs::operator()(FunctionSig* a, |
211 FunctionSig* b) const { | 199 FunctionSig* b) const { |
212 if (a->return_count() < b->return_count()) return true; | 200 if (a->return_count() < b->return_count()) return true; |
213 if (a->return_count() > b->return_count()) return false; | 201 if (a->return_count() > b->return_count()) return false; |
214 if (a->parameter_count() < b->parameter_count()) return true; | 202 if (a->parameter_count() < b->parameter_count()) return true; |
215 if (a->parameter_count() > b->parameter_count()) return false; | 203 if (a->parameter_count() > b->parameter_count()) return false; |
216 for (size_t r = 0; r < a->return_count(); r++) { | 204 for (size_t r = 0; r < a->return_count(); r++) { |
217 if (a->GetReturn(r) < b->GetReturn(r)) return true; | 205 if (a->GetReturn(r) < b->GetReturn(r)) return true; |
(...skipping 28 matching lines...) Expand all Loading... |
246 imports_.push_back({AddSignature(sig), name, name_length}); | 234 imports_.push_back({AddSignature(sig), name, name_length}); |
247 return static_cast<uint32_t>(imports_.size() - 1); | 235 return static_cast<uint32_t>(imports_.size() - 1); |
248 } | 236 } |
249 | 237 |
250 void WasmModuleBuilder::MarkStartFunction(WasmFunctionBuilder* function) { | 238 void WasmModuleBuilder::MarkStartFunction(WasmFunctionBuilder* function) { |
251 start_function_index_ = function->func_index(); | 239 start_function_index_ = function->func_index(); |
252 } | 240 } |
253 | 241 |
254 uint32_t WasmModuleBuilder::AddGlobal(LocalType type, bool exported, | 242 uint32_t WasmModuleBuilder::AddGlobal(LocalType type, bool exported, |
255 bool mutability) { | 243 bool mutability) { |
256 globals_.push_back(std::make_tuple(type, exported, mutability)); | 244 globals_.push_back({type, exported, mutability}); |
257 return static_cast<uint32_t>(globals_.size() - 1); | 245 return static_cast<uint32_t>(globals_.size() - 1); |
258 } | 246 } |
259 | 247 |
260 void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { | 248 void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { |
261 uint32_t exports = 0; | 249 uint32_t exports = 0; |
262 | 250 |
263 // == Emit magic ============================================================= | 251 // == Emit magic ============================================================= |
264 TRACE("emit magic\n"); | 252 TRACE("emit magic\n"); |
265 buffer.write_u32(kWasmMagic); | 253 buffer.write_u32(kWasmMagic); |
266 buffer.write_u32(kWasmVersion); | 254 buffer.write_u32(kWasmVersion); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 buffer.write_u32v(16); // max memory size | 320 buffer.write_u32v(16); // max memory size |
333 FixupSection(buffer, start); | 321 FixupSection(buffer, start); |
334 } | 322 } |
335 | 323 |
336 // == Emit globals =========================================================== | 324 // == Emit globals =========================================================== |
337 if (globals_.size() > 0) { | 325 if (globals_.size() > 0) { |
338 size_t start = EmitSection(kGlobalSectionCode, buffer); | 326 size_t start = EmitSection(kGlobalSectionCode, buffer); |
339 buffer.write_size(globals_.size()); | 327 buffer.write_size(globals_.size()); |
340 | 328 |
341 for (auto global : globals_) { | 329 for (auto global : globals_) { |
342 static const int kLocalTypeIndex = 0; | 330 buffer.write_u8(WasmOpcodes::LocalTypeCodeFor(global.type)); |
343 static const int kMutabilityIndex = 2; | 331 buffer.write_u8(global.mutability ? 1 : 0); |
344 buffer.write_u8( | 332 switch (global.type) { |
345 WasmOpcodes::LocalTypeCodeFor(std::get<kLocalTypeIndex>(global))); | |
346 buffer.write_u8(std::get<kMutabilityIndex>(global)); | |
347 switch (std::get<kLocalTypeIndex>(global)) { | |
348 case kAstI32: { | 333 case kAstI32: { |
349 static const byte code[] = {WASM_I32V_1(0)}; | 334 static const byte code[] = {WASM_I32V_1(0)}; |
350 buffer.write(code, sizeof(code)); | 335 buffer.write(code, sizeof(code)); |
351 break; | 336 break; |
352 } | 337 } |
353 case kAstF32: { | 338 case kAstF32: { |
354 static const byte code[] = {WASM_F32(0)}; | 339 static const byte code[] = {WASM_F32(0)}; |
355 buffer.write(code, sizeof(code)); | 340 buffer.write(code, sizeof(code)); |
356 break; | 341 break; |
357 } | 342 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 } | 399 } |
415 FixupSection(buffer, start); | 400 FixupSection(buffer, start); |
416 } | 401 } |
417 | 402 |
418 // == emit data segments ===================================================== | 403 // == emit data segments ===================================================== |
419 if (data_segments_.size() > 0) { | 404 if (data_segments_.size() > 0) { |
420 size_t start = EmitSection(kDataSectionCode, buffer); | 405 size_t start = EmitSection(kDataSectionCode, buffer); |
421 buffer.write_size(data_segments_.size()); | 406 buffer.write_size(data_segments_.size()); |
422 | 407 |
423 for (auto segment : data_segments_) { | 408 for (auto segment : data_segments_) { |
424 segment->Write(buffer); | 409 buffer.write_u8(0); // linear memory segment |
| 410 buffer.write_u8(kExprI32Const); // initializer expression for dest |
| 411 buffer.write_u32v(segment.dest); |
| 412 buffer.write_u8(kExprEnd); |
| 413 buffer.write_u32v(static_cast<uint32_t>(segment.data.size())); |
| 414 buffer.write(&segment.data[0], segment.data.size()); |
425 } | 415 } |
426 FixupSection(buffer, start); | 416 FixupSection(buffer, start); |
427 } | 417 } |
428 | 418 |
429 // == Emit names ============================================================= | 419 // == Emit names ============================================================= |
430 if (has_names) { | 420 if (has_names) { |
431 // Emit the section code. | 421 // Emit the section code. |
432 buffer.write_u8(kUnknownSectionCode); | 422 buffer.write_u8(kUnknownSectionCode); |
433 // Emit a placeholder for the length. | 423 // Emit a placeholder for the length. |
434 size_t start = buffer.reserve_u32v(); | 424 size_t start = buffer.reserve_u32v(); |
435 // Emit the section string. | 425 // Emit the section string. |
436 buffer.write_size(4); | 426 buffer.write_size(4); |
437 buffer.write(reinterpret_cast<const byte*>("name"), 4); | 427 buffer.write(reinterpret_cast<const byte*>("name"), 4); |
438 // Emit the names. | 428 // Emit the names. |
439 buffer.write_size(functions_.size()); | 429 buffer.write_size(functions_.size()); |
440 for (auto function : functions_) { | 430 for (auto function : functions_) { |
441 buffer.write_size(function->name_.size()); | 431 buffer.write_size(function->name_.size()); |
442 if (function->name_.size() > 0) { | 432 if (function->name_.size() > 0) { |
443 buffer.write(reinterpret_cast<const byte*>(&function->name_[0]), | 433 buffer.write(reinterpret_cast<const byte*>(&function->name_[0]), |
444 function->name_.size()); | 434 function->name_.size()); |
445 } | 435 } |
446 buffer.write_u8(0); | 436 buffer.write_u8(0); |
447 } | 437 } |
448 FixupSection(buffer, start); | 438 FixupSection(buffer, start); |
449 } | 439 } |
450 } | 440 } |
451 } // namespace wasm | 441 } // namespace wasm |
452 } // namespace internal | 442 } // namespace internal |
453 } // namespace v8 | 443 } // namespace v8 |
OLD | NEW |