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-containers.h" | 9 #include "src/zone-containers.h" |
10 | 10 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 // Emit a placeholder for the length. | 43 // Emit a placeholder for the length. |
44 return buffer.reserve_u32v(); | 44 return buffer.reserve_u32v(); |
45 } | 45 } |
46 | 46 |
47 // Patch the size of a section after it's finished. | 47 // Patch the size of a section after it's finished. |
48 void FixupSection(ZoneBuffer& buffer, size_t start) { | 48 void FixupSection(ZoneBuffer& buffer, size_t start) { |
49 buffer.patch_u32v(start, static_cast<uint32_t>(buffer.offset() - start - | 49 buffer.patch_u32v(start, static_cast<uint32_t>(buffer.offset() - start - |
50 kPaddedVarInt32Size)); | 50 kPaddedVarInt32Size)); |
51 } | 51 } |
52 | 52 |
53 WasmFunctionBuilder::WasmFunctionBuilder(Zone* zone) | 53 WasmFunctionBuilder::WasmFunctionBuilder(WasmModuleBuilder* builder) |
54 : locals_(zone), exported_(0), body_(zone), name_(zone) {} | 54 : builder_(builder), |
| 55 locals_(builder->zone()), |
| 56 signature_index_(0), |
| 57 exported_(0), |
| 58 body_(builder->zone()), |
| 59 name_(builder->zone()) {} |
55 | 60 |
56 void WasmFunctionBuilder::EmitVarInt(uint32_t val) { | 61 void WasmFunctionBuilder::EmitVarInt(uint32_t val) { |
57 byte buffer[8]; | 62 byte buffer[8]; |
58 byte* ptr = buffer; | 63 byte* ptr = buffer; |
59 LEBHelper::write_u32v(&ptr, val); | 64 LEBHelper::write_u32v(&ptr, val); |
60 for (byte* p = buffer; p < ptr; p++) { | 65 for (byte* p = buffer; p < ptr; p++) { |
61 body_.push_back(*p); | 66 body_.push_back(*p); |
62 } | 67 } |
63 } | 68 } |
64 | 69 |
65 void WasmFunctionBuilder::SetSignature(FunctionSig* sig) { | 70 void WasmFunctionBuilder::SetSignature(FunctionSig* sig) { |
66 DCHECK(!locals_.has_sig()); | 71 DCHECK(!locals_.has_sig()); |
67 locals_.set_sig(sig); | 72 locals_.set_sig(sig); |
| 73 signature_index_ = builder_->AddSignature(sig); |
68 } | 74 } |
69 | 75 |
70 uint32_t WasmFunctionBuilder::AddLocal(LocalType type) { | 76 uint32_t WasmFunctionBuilder::AddLocal(LocalType type) { |
71 DCHECK(locals_.has_sig()); | 77 DCHECK(locals_.has_sig()); |
72 return locals_.AddLocals(1, type); | 78 return locals_.AddLocals(1, type); |
73 } | 79 } |
74 | 80 |
75 void WasmFunctionBuilder::EmitGetLocal(uint32_t local_index) { | 81 void WasmFunctionBuilder::EmitGetLocal(uint32_t local_index) { |
76 EmitWithVarInt(kExprGetLocal, local_index); | 82 EmitWithVarInt(kExprGetLocal, local_index); |
77 } | 83 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 void WasmFunctionBuilder::EmitI32Const(int32_t value) { | 117 void WasmFunctionBuilder::EmitI32Const(int32_t value) { |
112 // TODO(titzer): variable-length signed and unsigned i32 constants. | 118 // TODO(titzer): variable-length signed and unsigned i32 constants. |
113 if (-128 <= value && value <= 127) { | 119 if (-128 <= value && value <= 127) { |
114 EmitWithU8(kExprI8Const, static_cast<byte>(value)); | 120 EmitWithU8(kExprI8Const, static_cast<byte>(value)); |
115 } else { | 121 } else { |
116 byte code[] = {WASM_I32V_5(value)}; | 122 byte code[] = {WASM_I32V_5(value)}; |
117 EmitCode(code, sizeof(code)); | 123 EmitCode(code, sizeof(code)); |
118 } | 124 } |
119 } | 125 } |
120 | 126 |
121 void WasmFunctionBuilder::Exported(uint8_t flag) { exported_ = flag; } | 127 void WasmFunctionBuilder::SetExported() { exported_ = true; } |
122 | 128 |
123 void WasmFunctionBuilder::SetName(const char* name, int name_length) { | 129 void WasmFunctionBuilder::SetName(const char* name, int name_length) { |
124 name_.clear(); | 130 name_.clear(); |
125 if (name_length > 0) { | 131 if (name_length > 0) { |
126 for (int i = 0; i < name_length; i++) { | 132 for (int i = 0; i < name_length; i++) { |
127 name_.push_back(*(name + i)); | 133 name_.push_back(*(name + i)); |
128 } | 134 } |
129 } | 135 } |
130 } | 136 } |
131 | 137 |
132 WasmFunctionEncoder* WasmFunctionBuilder::Build(Zone* zone, | 138 void WasmFunctionBuilder::WriteSignature(ZoneBuffer& buffer) const { |
133 WasmModuleBuilder* mb) const { | |
134 WasmFunctionEncoder* e = | |
135 new (zone) WasmFunctionEncoder(zone, locals_, exported_); | |
136 // TODO(titzer): lame memcpy here. | |
137 e->body_.insert(e->body_.begin(), body_.begin(), body_.end()); | |
138 e->signature_index_ = mb->AddSignature(locals_.get_sig()); | |
139 e->name_.insert(e->name_.begin(), name_.begin(), name_.end()); | |
140 return e; | |
141 } | |
142 | |
143 WasmFunctionEncoder::WasmFunctionEncoder(Zone* zone, LocalDeclEncoder locals, | |
144 bool exported) | |
145 : locals_(locals), exported_(exported), body_(zone), name_(zone) {} | |
146 | |
147 void WasmFunctionEncoder::WriteSignature(ZoneBuffer& buffer) const { | |
148 buffer.write_u32v(signature_index_); | 139 buffer.write_u32v(signature_index_); |
149 } | 140 } |
150 | 141 |
151 void WasmFunctionEncoder::WriteExport(ZoneBuffer& buffer, | 142 void WasmFunctionBuilder::WriteExport(ZoneBuffer& buffer, |
152 uint32_t func_index) const { | 143 uint32_t func_index) const { |
153 if (exported_) { | 144 if (exported_) { |
154 buffer.write_u32v(func_index); | 145 buffer.write_u32v(func_index); |
155 buffer.write_size(name_.size()); | 146 buffer.write_size(name_.size()); |
156 if (name_.size() > 0) { | 147 if (name_.size() > 0) { |
157 buffer.write(reinterpret_cast<const byte*>(&name_[0]), name_.size()); | 148 buffer.write(reinterpret_cast<const byte*>(&name_[0]), name_.size()); |
158 } | 149 } |
159 } | 150 } |
160 } | 151 } |
161 | 152 |
162 void WasmFunctionEncoder::WriteBody(ZoneBuffer& buffer) const { | 153 void WasmFunctionBuilder::WriteBody(ZoneBuffer& buffer) const { |
163 size_t locals_size = locals_.Size(); | 154 size_t locals_size = locals_.Size(); |
164 buffer.write_size(locals_size + body_.size()); | 155 buffer.write_size(locals_size + body_.size()); |
165 buffer.EnsureSpace(locals_size); | 156 buffer.EnsureSpace(locals_size); |
166 byte** ptr = buffer.pos_ptr(); | 157 byte** ptr = buffer.pos_ptr(); |
167 locals_.Emit(*ptr); | 158 locals_.Emit(*ptr); |
168 (*ptr) += locals_size; // UGLY: manual bump of position pointer | 159 (*ptr) += locals_size; // UGLY: manual bump of position pointer |
169 if (body_.size() > 0) { | 160 if (body_.size() > 0) { |
170 buffer.write(&body_[0], body_.size()); | 161 buffer.write(&body_[0], body_.size()); |
171 } | 162 } |
172 } | 163 } |
(...skipping 17 matching lines...) Expand all Loading... |
190 signatures_(zone), | 181 signatures_(zone), |
191 imports_(zone), | 182 imports_(zone), |
192 functions_(zone), | 183 functions_(zone), |
193 data_segments_(zone), | 184 data_segments_(zone), |
194 indirect_functions_(zone), | 185 indirect_functions_(zone), |
195 globals_(zone), | 186 globals_(zone), |
196 signature_map_(zone), | 187 signature_map_(zone), |
197 start_function_index_(-1) {} | 188 start_function_index_(-1) {} |
198 | 189 |
199 uint32_t WasmModuleBuilder::AddFunction() { | 190 uint32_t WasmModuleBuilder::AddFunction() { |
200 functions_.push_back(new (zone_) WasmFunctionBuilder(zone_)); | 191 functions_.push_back(new (zone_) WasmFunctionBuilder(this)); |
201 return static_cast<uint32_t>(functions_.size() - 1); | 192 return static_cast<uint32_t>(functions_.size() - 1); |
202 } | 193 } |
203 | 194 |
204 WasmFunctionBuilder* WasmModuleBuilder::FunctionAt(size_t index) { | 195 WasmFunctionBuilder* WasmModuleBuilder::FunctionAt(size_t index) { |
205 if (functions_.size() > index) { | 196 if (functions_.size() > index) { |
206 return functions_.at(index); | 197 return functions_.at(index); |
207 } else { | 198 } else { |
208 return nullptr; | 199 return nullptr; |
209 } | 200 } |
210 } | 201 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 uint32_t WasmModuleBuilder::AddImport(const char* name, int name_length, | 240 uint32_t WasmModuleBuilder::AddImport(const char* name, int name_length, |
250 FunctionSig* sig) { | 241 FunctionSig* sig) { |
251 imports_.push_back({AddSignature(sig), name, name_length}); | 242 imports_.push_back({AddSignature(sig), name, name_length}); |
252 return static_cast<uint32_t>(imports_.size() - 1); | 243 return static_cast<uint32_t>(imports_.size() - 1); |
253 } | 244 } |
254 | 245 |
255 void WasmModuleBuilder::MarkStartFunction(uint32_t index) { | 246 void WasmModuleBuilder::MarkStartFunction(uint32_t index) { |
256 start_function_index_ = index; | 247 start_function_index_ = index; |
257 } | 248 } |
258 | 249 |
259 WasmModuleWriter* WasmModuleBuilder::Build(Zone* zone) { | |
260 WasmModuleWriter* writer = new (zone) WasmModuleWriter(zone); | |
261 for (auto import : imports_) { | |
262 writer->imports_.push_back(import); | |
263 } | |
264 for (auto function : functions_) { | |
265 writer->functions_.push_back(function->Build(zone, this)); | |
266 } | |
267 for (auto segment : data_segments_) { | |
268 writer->data_segments_.push_back(segment); | |
269 } | |
270 for (auto sig : signatures_) { | |
271 writer->signatures_.push_back(sig); | |
272 } | |
273 for (auto index : indirect_functions_) { | |
274 writer->indirect_functions_.push_back(index); | |
275 } | |
276 for (auto global : globals_) { | |
277 writer->globals_.push_back(global); | |
278 } | |
279 writer->start_function_index_ = start_function_index_; | |
280 return writer; | |
281 } | |
282 | |
283 uint32_t WasmModuleBuilder::AddGlobal(MachineType type, bool exported) { | 250 uint32_t WasmModuleBuilder::AddGlobal(MachineType type, bool exported) { |
284 globals_.push_back(std::make_pair(type, exported)); | 251 globals_.push_back(std::make_pair(type, exported)); |
285 return static_cast<uint32_t>(globals_.size() - 1); | 252 return static_cast<uint32_t>(globals_.size() - 1); |
286 } | 253 } |
287 | 254 |
288 WasmModuleWriter::WasmModuleWriter(Zone* zone) | 255 void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { |
289 : imports_(zone), | |
290 functions_(zone), | |
291 data_segments_(zone), | |
292 signatures_(zone), | |
293 indirect_functions_(zone), | |
294 globals_(zone) {} | |
295 | |
296 void WasmModuleWriter::WriteTo(ZoneBuffer& buffer) const { | |
297 uint32_t exports = 0; | 256 uint32_t exports = 0; |
298 | 257 |
299 // == Emit magic ============================================================= | 258 // == Emit magic ============================================================= |
300 TRACE("emit magic\n"); | 259 TRACE("emit magic\n"); |
301 buffer.write_u32(kWasmMagic); | 260 buffer.write_u32(kWasmMagic); |
302 buffer.write_u32(kWasmVersion); | 261 buffer.write_u32(kWasmVersion); |
303 | 262 |
304 // == Emit signatures ======================================================== | 263 // == Emit signatures ======================================================== |
305 if (signatures_.size() > 0) { | 264 if (signatures_.size() > 0) { |
306 size_t start = EmitSection(WasmSection::Code::Signatures, buffer); | 265 size_t start = EmitSection(WasmSection::Code::Signatures, buffer); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 | 373 |
415 for (auto segment : data_segments_) { | 374 for (auto segment : data_segments_) { |
416 segment->Write(buffer); | 375 segment->Write(buffer); |
417 } | 376 } |
418 FixupSection(buffer, start); | 377 FixupSection(buffer, start); |
419 } | 378 } |
420 } | 379 } |
421 } // namespace wasm | 380 } // namespace wasm |
422 } // namespace internal | 381 } // namespace internal |
423 } // namespace v8 | 382 } // namespace v8 |
OLD | NEW |