Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <stack> | |
| 6 | |
| 7 #include "src/compiler.h" | |
| 8 #include "src/interpreter/bytecode-generator.h" | |
|
Michael Starzinger
2015/08/18 08:17:16
nit: Please move the include of bytecode-generator
oth
2015/08/18 10:56:10
Done.
| |
| 9 #include "src/objects.h" | |
| 10 #include "src/scopes.h" | |
| 11 #include "src/token.h" | |
| 12 | |
| 13 namespace v8 { | |
| 14 namespace internal { | |
| 15 namespace interpreter { | |
| 16 | |
| 17 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone) | |
| 18 : builder_(isolate) { | |
| 19 InitializeAstVisitor(isolate, zone); | |
| 20 } | |
| 21 | |
| 22 | |
| 23 BytecodeGenerator::~BytecodeGenerator() {} | |
| 24 | |
| 25 | |
| 26 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) { | |
| 27 set_scope(info->scope()); | |
| 28 DCHECK(scope()->is_function_scope()); | |
|
Michael Starzinger
2015/08/18 08:17:16
I assume this is just a temporary guard, because i
oth
2015/08/18 10:56:10
Yes, added a comment for other readers.
| |
| 29 | |
| 30 builder().set_locals_count(scope()->num_stack_slots()); | |
| 31 | |
| 32 // Visit implicit declaration of the function name. | |
| 33 if (scope()->is_function_scope() && scope()->function() != NULL) { | |
| 34 VisitVariableDeclaration(scope()->function()); | |
| 35 } | |
| 36 | |
| 37 // Visit declarations within the function scope. | |
| 38 VisitDeclarations(scope()->declarations()); | |
| 39 | |
| 40 // Visit statements in the function body. | |
| 41 VisitStatements(info->function()->body()); | |
| 42 | |
| 43 set_scope(nullptr); | |
| 44 return builder_.ToBytecodeArray(); | |
| 45 } | |
| 46 | |
| 47 | |
| 48 void BytecodeGenerator::VisitBlock(Block* node) { | |
| 49 if (node->scope() == NULL) { | |
| 50 // Visit statements in the same scope, no declarations. | |
| 51 VisitStatements(node->statements()); | |
| 52 } else { | |
| 53 // Visit declarations and statements in a block scope. | |
| 54 if (node->scope()->ContextLocalCount() > 0) { | |
| 55 UNIMPLEMENTED(); | |
| 56 } else { | |
| 57 VisitDeclarations(node->scope()->declarations()); | |
| 58 VisitStatements(node->statements()); | |
| 59 } | |
| 60 } | |
| 61 } | |
| 62 | |
| 63 | |
| 64 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { | |
| 65 Variable* variable = decl->proxy()->var(); | |
| 66 switch (variable->location()) { | |
| 67 case VariableLocation::GLOBAL: | |
| 68 case VariableLocation::UNALLOCATED: | |
| 69 UNIMPLEMENTED(); | |
| 70 break; | |
| 71 case VariableLocation::PARAMETER: | |
| 72 UNIMPLEMENTED(); | |
| 73 break; | |
| 74 case VariableLocation::LOCAL: | |
| 75 // Details stored in scope, i.e. variable index. | |
| 76 break; | |
| 77 case VariableLocation::CONTEXT: | |
| 78 case VariableLocation::LOOKUP: | |
| 79 UNIMPLEMENTED(); | |
| 80 break; | |
| 81 } | |
| 82 } | |
| 83 | |
| 84 | |
| 85 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* node) { | |
| 86 UNIMPLEMENTED(); | |
| 87 } | |
| 88 | |
| 89 | |
| 90 void BytecodeGenerator::VisitImportDeclaration(ImportDeclaration* node) { | |
| 91 UNIMPLEMENTED(); | |
| 92 } | |
| 93 | |
| 94 | |
| 95 void BytecodeGenerator::VisitExportDeclaration(ExportDeclaration* node) { | |
| 96 UNIMPLEMENTED(); | |
| 97 } | |
| 98 | |
| 99 | |
| 100 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { | |
| 101 stmt->expression()->Accept(this); | |
|
Michael Starzinger
2015/08/18 08:17:16
nit: Better use Visit(stmt) here. Performs stack-o
oth
2015/08/18 10:56:10
Done.
| |
| 102 } | |
| 103 | |
| 104 | |
| 105 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* node) { | |
| 106 UNIMPLEMENTED(); | |
| 107 } | |
| 108 | |
| 109 | |
| 110 void BytecodeGenerator::VisitIfStatement(IfStatement* node) { UNIMPLEMENTED(); } | |
| 111 | |
| 112 | |
| 113 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* node) { | |
| 114 UNIMPLEMENTED(); | |
| 115 } | |
| 116 | |
| 117 | |
| 118 void BytecodeGenerator::VisitBreakStatement(BreakStatement* node) { | |
| 119 UNIMPLEMENTED(); | |
| 120 } | |
| 121 | |
| 122 | |
| 123 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* node) { | |
| 124 Visit(node->expression()); | |
| 125 builder().Return(); | |
| 126 } | |
| 127 | |
| 128 | |
| 129 void BytecodeGenerator::VisitWithStatement(WithStatement* node) { | |
| 130 UNIMPLEMENTED(); | |
| 131 } | |
| 132 | |
| 133 | |
| 134 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* node) { | |
| 135 UNIMPLEMENTED(); | |
| 136 } | |
| 137 | |
| 138 | |
| 139 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { UNIMPLEMENTED(); } | |
| 140 | |
| 141 | |
| 142 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) { | |
| 143 UNIMPLEMENTED(); | |
| 144 } | |
| 145 | |
| 146 | |
| 147 void BytecodeGenerator::VisitWhileStatement(WhileStatement* node) { | |
| 148 UNIMPLEMENTED(); | |
| 149 } | |
| 150 | |
| 151 | |
| 152 void BytecodeGenerator::VisitForStatement(ForStatement* node) { | |
| 153 UNIMPLEMENTED(); | |
| 154 } | |
| 155 | |
| 156 | |
| 157 void BytecodeGenerator::VisitForInStatement(ForInStatement* node) { | |
| 158 UNIMPLEMENTED(); | |
| 159 } | |
| 160 | |
| 161 | |
| 162 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* node) { | |
| 163 UNIMPLEMENTED(); | |
| 164 } | |
| 165 | |
| 166 | |
| 167 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* node) { | |
| 168 UNIMPLEMENTED(); | |
| 169 } | |
| 170 | |
| 171 | |
| 172 void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* node) { | |
| 173 UNIMPLEMENTED(); | |
| 174 } | |
| 175 | |
| 176 | |
| 177 void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { | |
| 178 UNIMPLEMENTED(); | |
| 179 } | |
| 180 | |
| 181 | |
| 182 void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) { | |
| 183 UNIMPLEMENTED(); | |
| 184 } | |
| 185 | |
| 186 | |
| 187 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* node) { | |
| 188 UNIMPLEMENTED(); | |
| 189 } | |
| 190 | |
| 191 | |
| 192 void BytecodeGenerator::VisitNativeFunctionLiteral( | |
| 193 NativeFunctionLiteral* node) { | |
| 194 UNIMPLEMENTED(); | |
| 195 } | |
| 196 | |
| 197 | |
| 198 void BytecodeGenerator::VisitConditional(Conditional* node) { UNIMPLEMENTED(); } | |
| 199 | |
| 200 | |
| 201 void BytecodeGenerator::VisitLiteral(Literal* expr) { | |
| 202 if (expr->IsPropertyName()) { | |
| 203 UNIMPLEMENTED(); | |
| 204 } | |
| 205 | |
| 206 Handle<Object> value = expr->value(); | |
| 207 if (value->IsSmi()) { | |
| 208 builder().LoadLiteral(Smi::cast(*value)); | |
| 209 } else if (value->IsUndefined()) { | |
| 210 builder().LoadUndefined(); | |
| 211 } else if (value->IsTrue()) { | |
| 212 builder().LoadTrue(); | |
| 213 } else if (value->IsFalse()) { | |
| 214 builder().LoadFalse(); | |
| 215 } else if (value->IsNull()) { | |
| 216 builder().LoadNull(); | |
| 217 } else if (value->IsTheHole()) { | |
| 218 builder().LoadTheHole(); | |
| 219 } else { | |
| 220 UNIMPLEMENTED(); | |
| 221 } | |
| 222 } | |
| 223 | |
| 224 | |
| 225 void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { | |
| 226 UNIMPLEMENTED(); | |
| 227 } | |
| 228 | |
| 229 | |
| 230 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { | |
| 231 UNIMPLEMENTED(); | |
| 232 } | |
| 233 | |
| 234 | |
| 235 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { | |
| 236 UNIMPLEMENTED(); | |
| 237 } | |
| 238 | |
| 239 | |
| 240 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) { | |
| 241 Variable* variable = proxy->var(); | |
| 242 switch (variable->location()) { | |
| 243 case VariableLocation::LOCAL: { | |
| 244 Register source(variable->index()); | |
| 245 builder().LoadAccumulatorWithRegister(source); | |
| 246 break; | |
| 247 } | |
| 248 case VariableLocation::GLOBAL: | |
| 249 case VariableLocation::UNALLOCATED: | |
| 250 case VariableLocation::PARAMETER: | |
| 251 case VariableLocation::CONTEXT: | |
| 252 case VariableLocation::LOOKUP: | |
| 253 UNIMPLEMENTED(); | |
| 254 } | |
| 255 } | |
| 256 | |
| 257 | |
| 258 void BytecodeGenerator::VisitAssignment(Assignment* expr) { | |
| 259 DCHECK(expr->target()->IsValidReferenceExpression()); | |
| 260 | |
| 261 // Left-hand side can only be a property, a global or a variable slot. | |
| 262 Property* property = expr->target()->AsProperty(); | |
| 263 LhsKind assign_type = Property::GetAssignType(property); | |
| 264 | |
| 265 DCHECK(!expr->is_compound()); | |
| 266 Visit(expr->value()); | |
| 267 | |
| 268 switch (assign_type) { | |
| 269 case VARIABLE: { | |
| 270 Variable* variable = expr->target()->AsVariableProxy()->var(); | |
| 271 DCHECK(variable->location() == VariableLocation::LOCAL); | |
| 272 Register destination(variable->index()); | |
| 273 builder().StoreAccumulatorInRegister(destination); | |
| 274 break; | |
| 275 } | |
| 276 case NAMED_PROPERTY: | |
| 277 case KEYED_PROPERTY: | |
| 278 case NAMED_SUPER_PROPERTY: | |
| 279 case KEYED_SUPER_PROPERTY: | |
| 280 UNIMPLEMENTED(); | |
| 281 } | |
| 282 } | |
| 283 | |
| 284 | |
| 285 void BytecodeGenerator::VisitYield(Yield* node) { UNIMPLEMENTED(); } | |
| 286 | |
| 287 | |
| 288 void BytecodeGenerator::VisitThrow(Throw* node) { UNIMPLEMENTED(); } | |
| 289 | |
| 290 | |
| 291 void BytecodeGenerator::VisitProperty(Property* node) { UNIMPLEMENTED(); } | |
| 292 | |
| 293 | |
| 294 void BytecodeGenerator::VisitCall(Call* node) { UNIMPLEMENTED(); } | |
| 295 | |
| 296 | |
| 297 void BytecodeGenerator::VisitCallNew(CallNew* node) { UNIMPLEMENTED(); } | |
| 298 | |
| 299 | |
| 300 void BytecodeGenerator::VisitCallRuntime(CallRuntime* node) { UNIMPLEMENTED(); } | |
| 301 | |
| 302 | |
| 303 void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* node) { | |
| 304 UNIMPLEMENTED(); | |
| 305 } | |
| 306 | |
| 307 | |
| 308 void BytecodeGenerator::VisitCountOperation(CountOperation* node) { | |
| 309 UNIMPLEMENTED(); | |
| 310 } | |
| 311 | |
| 312 | |
| 313 void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) { | |
| 314 switch (binop->op()) { | |
| 315 case Token::COMMA: | |
| 316 case Token::OR: | |
| 317 case Token::AND: | |
| 318 UNIMPLEMENTED(); | |
| 319 break; | |
| 320 default: | |
| 321 VisitArithmeticExpression(binop); | |
| 322 break; | |
| 323 } | |
| 324 } | |
| 325 | |
| 326 | |
| 327 void BytecodeGenerator::VisitCompareOperation(CompareOperation* node) { | |
| 328 UNIMPLEMENTED(); | |
| 329 } | |
| 330 | |
| 331 | |
| 332 void BytecodeGenerator::VisitSpread(Spread* node) { UNIMPLEMENTED(); } | |
| 333 | |
| 334 | |
| 335 void BytecodeGenerator::VisitThisFunction(ThisFunction* node) { | |
| 336 UNIMPLEMENTED(); | |
| 337 } | |
| 338 | |
| 339 | |
| 340 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* node) { | |
| 341 UNIMPLEMENTED(); | |
| 342 } | |
| 343 | |
| 344 | |
| 345 void BytecodeGenerator::VisitSuperPropertyReference( | |
| 346 SuperPropertyReference* node) { | |
| 347 UNIMPLEMENTED(); | |
| 348 } | |
| 349 | |
| 350 | |
| 351 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* binop) { | |
| 352 Token::Value op = binop->op(); | |
| 353 Expression* left = binop->left(); | |
| 354 Expression* right = binop->right(); | |
| 355 | |
| 356 TemporaryRegisterScope temporary_register_scope(&builder_); | |
| 357 Register temporary = temporary_register_scope.NewRegister(); | |
| 358 | |
| 359 Visit(left); | |
| 360 builder().StoreAccumulatorInRegister(temporary); | |
| 361 Visit(right); | |
| 362 builder().BinaryOperation(op, temporary); | |
| 363 } | |
| 364 | |
| 365 } // namespace interpreter | |
| 366 } // namespace internal | |
| 367 } // namespace v8 | |
| OLD | NEW |