| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 // Required to get M_E etc. in MSVC. | 7 // Required to get M_E etc. in MSVC. |
| 8 #if defined(_WIN32) | 8 #if defined(_WIN32) |
| 9 #define _USE_MATH_DEFINES | 9 #define _USE_MATH_DEFINES |
| 10 #endif | 10 #endif |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 int prev_block_size_; | 131 int prev_block_size_; |
| 132 uint32_t index_; | 132 uint32_t index_; |
| 133 AsmWasmBuilderImpl* builder_; | 133 AsmWasmBuilderImpl* builder_; |
| 134 | 134 |
| 135 public: | 135 public: |
| 136 BlockVisitor(AsmWasmBuilderImpl* builder, BreakableStatement* stmt, | 136 BlockVisitor(AsmWasmBuilderImpl* builder, BreakableStatement* stmt, |
| 137 WasmOpcode opcode, bool is_loop, int initial_block_size) | 137 WasmOpcode opcode, bool is_loop, int initial_block_size) |
| 138 : builder_(builder) { | 138 : builder_(builder) { |
| 139 builder_->breakable_blocks_.push_back(std::make_pair(stmt, is_loop)); | 139 builder_->breakable_blocks_.push_back(std::make_pair(stmt, is_loop)); |
| 140 builder_->current_function_builder_->Emit(opcode); | 140 builder_->current_function_builder_->Emit(opcode); |
| 141 index_ = builder_->current_function_builder_->EmitEditableImmediate(0); | 141 index_ = |
| 142 builder_->current_function_builder_->EmitEditableVarIntImmediate(); |
| 142 prev_block_size_ = builder_->block_size_; | 143 prev_block_size_ = builder_->block_size_; |
| 143 builder_->block_size_ = initial_block_size; | 144 builder_->block_size_ = initial_block_size; |
| 144 } | 145 } |
| 145 ~BlockVisitor() { | 146 ~BlockVisitor() { |
| 146 builder_->current_function_builder_->EditImmediate(index_, | 147 builder_->current_function_builder_->EditVarIntImmediate( |
| 147 builder_->block_size_); | 148 index_, builder_->block_size_); |
| 148 builder_->block_size_ = prev_block_size_; | 149 builder_->block_size_ = prev_block_size_; |
| 149 builder_->breakable_blocks_.pop_back(); | 150 builder_->breakable_blocks_.pop_back(); |
| 150 } | 151 } |
| 151 }; | 152 }; |
| 152 | 153 |
| 153 void VisitExpressionStatement(ExpressionStatement* stmt) { | 154 void VisitExpressionStatement(ExpressionStatement* stmt) { |
| 154 RECURSE(Visit(stmt->expression())); | 155 RECURSE(Visit(stmt->expression())); |
| 155 } | 156 } |
| 156 | 157 |
| 157 void VisitEmptyStatement(EmptyStatement* stmt) {} | 158 void VisitEmptyStatement(EmptyStatement* stmt) {} |
| (...skipping 28 matching lines...) Expand all Loading... |
| 186 if (elem.first == stmt->target()) { | 187 if (elem.first == stmt->target()) { |
| 187 DCHECK(elem.second); | 188 DCHECK(elem.second); |
| 188 break; | 189 break; |
| 189 } else if (elem.second) { | 190 } else if (elem.second) { |
| 190 block_distance += 2; | 191 block_distance += 2; |
| 191 } else { | 192 } else { |
| 192 block_distance += 1; | 193 block_distance += 1; |
| 193 } | 194 } |
| 194 } | 195 } |
| 195 DCHECK(i >= 0); | 196 DCHECK(i >= 0); |
| 196 current_function_builder_->EmitWithU8(kExprBr, block_distance); | 197 current_function_builder_->EmitWithVarInt(kExprBr, block_distance); |
| 197 current_function_builder_->Emit(kExprNop); | 198 current_function_builder_->Emit(kExprNop); |
| 198 } | 199 } |
| 199 | 200 |
| 200 void VisitBreakStatement(BreakStatement* stmt) { | 201 void VisitBreakStatement(BreakStatement* stmt) { |
| 201 DCHECK(in_function_); | 202 DCHECK(in_function_); |
| 202 DCHECK_NOT_NULL(stmt->target()); | 203 DCHECK_NOT_NULL(stmt->target()); |
| 203 int i = static_cast<int>(breakable_blocks_.size()) - 1; | 204 int i = static_cast<int>(breakable_blocks_.size()) - 1; |
| 204 int block_distance = 0; | 205 int block_distance = 0; |
| 205 for (; i >= 0; i--) { | 206 for (; i >= 0; i--) { |
| 206 auto elem = breakable_blocks_.at(i); | 207 auto elem = breakable_blocks_.at(i); |
| 207 if (elem.first == stmt->target()) { | 208 if (elem.first == stmt->target()) { |
| 208 if (elem.second) { | 209 if (elem.second) { |
| 209 block_distance++; | 210 block_distance++; |
| 210 } | 211 } |
| 211 break; | 212 break; |
| 212 } else if (elem.second) { | 213 } else if (elem.second) { |
| 213 block_distance += 2; | 214 block_distance += 2; |
| 214 } else { | 215 } else { |
| 215 block_distance += 1; | 216 block_distance += 1; |
| 216 } | 217 } |
| 217 } | 218 } |
| 218 DCHECK(i >= 0); | 219 DCHECK(i >= 0); |
| 219 current_function_builder_->EmitWithU8(kExprBr, block_distance); | 220 current_function_builder_->EmitWithVarInt(kExprBr, block_distance); |
| 220 current_function_builder_->Emit(kExprNop); | 221 current_function_builder_->Emit(kExprNop); |
| 221 } | 222 } |
| 222 | 223 |
| 223 void VisitReturnStatement(ReturnStatement* stmt) { | 224 void VisitReturnStatement(ReturnStatement* stmt) { |
| 224 if (in_function_) { | 225 if (in_function_) { |
| 225 current_function_builder_->Emit(kExprReturn); | 226 current_function_builder_->Emit(kExprReturn); |
| 226 } else { | 227 } else { |
| 227 marking_exported = true; | 228 marking_exported = true; |
| 228 } | 229 } |
| 229 RECURSE(Visit(stmt->expression())); | 230 RECURSE(Visit(stmt->expression())); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 | 286 |
| 286 void VisitCaseClause(CaseClause* clause) { UNREACHABLE(); } | 287 void VisitCaseClause(CaseClause* clause) { UNREACHABLE(); } |
| 287 | 288 |
| 288 void VisitDoWhileStatement(DoWhileStatement* stmt) { | 289 void VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 289 DCHECK(in_function_); | 290 DCHECK(in_function_); |
| 290 BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprLoop, true, | 291 BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprLoop, true, |
| 291 2); | 292 2); |
| 292 RECURSE(Visit(stmt->body())); | 293 RECURSE(Visit(stmt->body())); |
| 293 current_function_builder_->Emit(kExprIf); | 294 current_function_builder_->Emit(kExprIf); |
| 294 RECURSE(Visit(stmt->cond())); | 295 RECURSE(Visit(stmt->cond())); |
| 295 current_function_builder_->EmitWithU8(kExprBr, 0); | 296 current_function_builder_->EmitWithVarInt(kExprBr, 0); |
| 296 current_function_builder_->Emit(kExprNop); | 297 current_function_builder_->Emit(kExprNop); |
| 297 } | 298 } |
| 298 | 299 |
| 299 void VisitWhileStatement(WhileStatement* stmt) { | 300 void VisitWhileStatement(WhileStatement* stmt) { |
| 300 DCHECK(in_function_); | 301 DCHECK(in_function_); |
| 301 BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprLoop, true, | 302 BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprLoop, true, |
| 302 1); | 303 1); |
| 303 current_function_builder_->Emit(kExprIf); | 304 current_function_builder_->Emit(kExprIf); |
| 304 RECURSE(Visit(stmt->cond())); | 305 RECURSE(Visit(stmt->cond())); |
| 305 current_function_builder_->EmitWithU8(kExprBr, 0); | 306 current_function_builder_->EmitWithVarInt(kExprBr, 0); |
| 306 RECURSE(Visit(stmt->body())); | 307 RECURSE(Visit(stmt->body())); |
| 307 } | 308 } |
| 308 | 309 |
| 309 void VisitForStatement(ForStatement* stmt) { | 310 void VisitForStatement(ForStatement* stmt) { |
| 310 DCHECK(in_function_); | 311 DCHECK(in_function_); |
| 311 if (stmt->init() != nullptr) { | 312 if (stmt->init() != nullptr) { |
| 312 block_size_++; | 313 block_size_++; |
| 313 RECURSE(Visit(stmt->init())); | 314 RECURSE(Visit(stmt->init())); |
| 314 } | 315 } |
| 315 BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprLoop, true, | 316 BlockVisitor visitor(this, stmt->AsBreakableStatement(), kExprLoop, true, |
| 316 0); | 317 0); |
| 317 if (stmt->cond() != nullptr) { | 318 if (stmt->cond() != nullptr) { |
| 318 block_size_++; | 319 block_size_++; |
| 319 current_function_builder_->Emit(kExprIf); | 320 current_function_builder_->Emit(kExprIf); |
| 320 current_function_builder_->Emit(kExprI32Eqz); | 321 current_function_builder_->Emit(kExprI32Eqz); |
| 321 RECURSE(Visit(stmt->cond())); | 322 RECURSE(Visit(stmt->cond())); |
| 322 current_function_builder_->EmitWithU8(kExprBr, 1); | 323 current_function_builder_->EmitWithVarInt(kExprBr, 1); |
| 323 current_function_builder_->Emit(kExprNop); | 324 current_function_builder_->Emit(kExprNop); |
| 324 } | 325 } |
| 325 if (stmt->body() != nullptr) { | 326 if (stmt->body() != nullptr) { |
| 326 block_size_++; | 327 block_size_++; |
| 327 RECURSE(Visit(stmt->body())); | 328 RECURSE(Visit(stmt->body())); |
| 328 } | 329 } |
| 329 if (stmt->next() != nullptr) { | 330 if (stmt->next() != nullptr) { |
| 330 block_size_++; | 331 block_size_++; |
| 331 RECURSE(Visit(stmt->next())); | 332 RECURSE(Visit(stmt->next())); |
| 332 } | 333 } |
| 333 block_size_++; | 334 block_size_++; |
| 334 current_function_builder_->EmitWithU8(kExprBr, 0); | 335 current_function_builder_->EmitWithVarInt(kExprBr, 0); |
| 335 current_function_builder_->Emit(kExprNop); | 336 current_function_builder_->Emit(kExprNop); |
| 336 } | 337 } |
| 337 | 338 |
| 338 void VisitForInStatement(ForInStatement* stmt) { UNREACHABLE(); } | 339 void VisitForInStatement(ForInStatement* stmt) { UNREACHABLE(); } |
| 339 | 340 |
| 340 void VisitForOfStatement(ForOfStatement* stmt) { UNREACHABLE(); } | 341 void VisitForOfStatement(ForOfStatement* stmt) { UNREACHABLE(); } |
| 341 | 342 |
| 342 void VisitTryCatchStatement(TryCatchStatement* stmt) { UNREACHABLE(); } | 343 void VisitTryCatchStatement(TryCatchStatement* stmt) { UNREACHABLE(); } |
| 343 | 344 |
| 344 void VisitTryFinallyStatement(TryFinallyStatement* stmt) { UNREACHABLE(); } | 345 void VisitTryFinallyStatement(TryFinallyStatement* stmt) { UNREACHABLE(); } |
| (...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1051 &index_arr[0], static_cast<uint32_t>(index_arr.size())); | 1052 &index_arr[0], static_cast<uint32_t>(index_arr.size())); |
| 1052 break; | 1053 break; |
| 1053 } | 1054 } |
| 1054 case Call::KEYED_PROPERTY_CALL: { | 1055 case Call::KEYED_PROPERTY_CALL: { |
| 1055 DCHECK(in_function_); | 1056 DCHECK(in_function_); |
| 1056 Property* p = expr->expression()->AsProperty(); | 1057 Property* p = expr->expression()->AsProperty(); |
| 1057 DCHECK_NOT_NULL(p); | 1058 DCHECK_NOT_NULL(p); |
| 1058 VariableProxy* var = p->obj()->AsVariableProxy(); | 1059 VariableProxy* var = p->obj()->AsVariableProxy(); |
| 1059 DCHECK_NOT_NULL(var); | 1060 DCHECK_NOT_NULL(var); |
| 1060 FunctionTableIndices* indices = LookupFunctionTable(var->var()); | 1061 FunctionTableIndices* indices = LookupFunctionTable(var->var()); |
| 1061 current_function_builder_->EmitWithU8(kExprCallIndirect, | 1062 current_function_builder_->EmitWithVarInt(kExprCallIndirect, |
| 1062 indices->signature_index); | 1063 indices->signature_index); |
| 1063 current_function_builder_->Emit(kExprI32Add); | 1064 current_function_builder_->Emit(kExprI32Add); |
| 1064 // TODO(bradnelson): variable size | 1065 // TODO(bradnelson): variable size |
| 1065 byte code[] = {WASM_I32V(indices->start_index)}; | 1066 byte code[] = {WASM_I32V(indices->start_index)}; |
| 1066 current_function_builder_->EmitCode(code, sizeof(code)); | 1067 current_function_builder_->EmitCode(code, sizeof(code)); |
| 1067 RECURSE(Visit(p->key())); | 1068 RECURSE(Visit(p->key())); |
| 1068 break; | 1069 break; |
| 1069 } | 1070 } |
| 1070 default: | 1071 default: |
| 1071 UNREACHABLE(); | 1072 UNREACHABLE(); |
| 1072 } | 1073 } |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1276 current_function_builder_->Emit(kExprI32RemU); | 1277 current_function_builder_->Emit(kExprI32RemU); |
| 1277 } else if (type == kFloat64) { | 1278 } else if (type == kFloat64) { |
| 1278 current_function_builder_->Emit(kExprF64Mod); | 1279 current_function_builder_->Emit(kExprF64Mod); |
| 1279 return; | 1280 return; |
| 1280 } else { | 1281 } else { |
| 1281 UNREACHABLE(); | 1282 UNREACHABLE(); |
| 1282 } | 1283 } |
| 1283 break; | 1284 break; |
| 1284 } | 1285 } |
| 1285 case Token::COMMA: { | 1286 case Token::COMMA: { |
| 1286 current_function_builder_->EmitWithU8(kExprBlock, 2); | 1287 current_function_builder_->EmitWithVarInt(kExprBlock, 2); |
| 1287 break; | 1288 break; |
| 1288 } | 1289 } |
| 1289 default: | 1290 default: |
| 1290 UNREACHABLE(); | 1291 UNREACHABLE(); |
| 1291 } | 1292 } |
| 1292 RECURSE(Visit(expr->left())); | 1293 RECURSE(Visit(expr->left())); |
| 1293 RECURSE(Visit(expr->right())); | 1294 RECURSE(Visit(expr->right())); |
| 1294 } | 1295 } |
| 1295 } | 1296 } |
| 1296 | 1297 |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1517 // that zone in constructor may be thrown away once wasm module is written. | 1518 // that zone in constructor may be thrown away once wasm module is written. |
| 1518 WasmModuleIndex* AsmWasmBuilder::Run() { | 1519 WasmModuleIndex* AsmWasmBuilder::Run() { |
| 1519 AsmWasmBuilderImpl impl(isolate_, zone_, literal_, foreign_, typer_); | 1520 AsmWasmBuilderImpl impl(isolate_, zone_, literal_, foreign_, typer_); |
| 1520 impl.Compile(); | 1521 impl.Compile(); |
| 1521 WasmModuleWriter* writer = impl.builder_->Build(zone_); | 1522 WasmModuleWriter* writer = impl.builder_->Build(zone_); |
| 1522 return writer->WriteTo(zone_); | 1523 return writer->WriteTo(zone_); |
| 1523 } | 1524 } |
| 1524 } // namespace wasm | 1525 } // namespace wasm |
| 1525 } // namespace internal | 1526 } // namespace internal |
| 1526 } // namespace v8 | 1527 } // namespace v8 |
| OLD | NEW |