| 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 |