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" | |
| 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()); | |
| 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, ie variable index. | |
|
rmcilroy
2015/08/14 09:31:17
/s/ie/i.e.
oth
2015/08/17 08:05:48
Done.
| |
| 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); | |
| 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 DCHECK(!expr->IsPropertyName()); | |
|
rmcilroy
2015/08/14 09:31:17
Could you make this an if/else or switch statement
oth
2015/08/17 08:05:49
Done.
| |
| 203 Handle<Object> value = expr->value(); | |
| 204 if (value->IsSmi()) { | |
| 205 builder().LoadLiteral(Smi::cast(*value)); | |
| 206 } else if (value->IsUndefined()) { | |
| 207 builder().LoadUndefined(); | |
| 208 } else if (value->IsTrue()) { | |
| 209 builder().LoadTrue(); | |
| 210 } else if (value->IsFalse()) { | |
| 211 builder().LoadFalse(); | |
| 212 } else if (value->IsNull()) { | |
| 213 builder().LoadNull(); | |
| 214 } else if (value->IsTheHole()) { | |
| 215 builder().LoadTheHole(); | |
| 216 } else { | |
| 217 UNIMPLEMENTED(); | |
| 218 } | |
| 219 } | |
| 220 | |
| 221 | |
| 222 void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { | |
| 223 UNIMPLEMENTED(); | |
| 224 } | |
| 225 | |
| 226 | |
| 227 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { | |
| 228 UNIMPLEMENTED(); | |
| 229 } | |
| 230 | |
| 231 | |
| 232 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { | |
| 233 UNIMPLEMENTED(); | |
| 234 } | |
| 235 | |
| 236 | |
| 237 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) { | |
| 238 Variable* variable = proxy->var(); | |
| 239 DCHECK(variable->location() == VariableLocation::LOCAL); | |
|
rmcilroy
2015/08/14 09:31:17
Could you do this as a switch statement, with all
oth
2015/08/17 08:05:49
Done.
| |
| 240 Register source(variable->index()); | |
| 241 builder().LoadAccumulatorWithRegister(source); | |
| 242 } | |
| 243 | |
| 244 | |
| 245 void BytecodeGenerator::VisitAssignment(Assignment* expr) { | |
| 246 DCHECK(expr->target()->IsValidReferenceExpression()); | |
| 247 | |
| 248 // Left-hand side can only be a property, a global or a variable slot. | |
| 249 Property* property = expr->target()->AsProperty(); | |
| 250 LhsKind assign_type = Property::GetAssignType(property); | |
| 251 int destination = -1; | |
| 252 switch (assign_type) { | |
| 253 case VARIABLE: { | |
| 254 Variable* variable = expr->target()->AsVariableProxy()->var(); | |
| 255 destination = variable->index(); | |
| 256 DCHECK(variable->location() == VariableLocation::LOCAL); | |
| 257 break; | |
| 258 } | |
| 259 case NAMED_PROPERTY: | |
| 260 case KEYED_PROPERTY: | |
| 261 case NAMED_SUPER_PROPERTY: | |
| 262 case KEYED_SUPER_PROPERTY: | |
| 263 UNIMPLEMENTED(); | |
| 264 } | |
| 265 | |
| 266 DCHECK(!expr->is_compound()); | |
| 267 Visit(expr->value()); | |
| 268 builder().StoreAccumulatorInRegister(Register(destination)); | |
|
rmcilroy
2015/08/14 09:31:17
We would only be storing the value in a register i
oth
2015/08/17 08:05:49
Done.
| |
| 269 } | |
| 270 | |
| 271 | |
| 272 void BytecodeGenerator::VisitYield(Yield* node) { UNIMPLEMENTED(); } | |
| 273 | |
| 274 | |
| 275 void BytecodeGenerator::VisitThrow(Throw* node) { UNIMPLEMENTED(); } | |
| 276 | |
| 277 | |
| 278 void BytecodeGenerator::VisitProperty(Property* node) { UNIMPLEMENTED(); } | |
| 279 | |
| 280 | |
| 281 void BytecodeGenerator::VisitCall(Call* node) { UNIMPLEMENTED(); } | |
| 282 | |
| 283 | |
| 284 void BytecodeGenerator::VisitCallNew(CallNew* node) { UNIMPLEMENTED(); } | |
| 285 | |
| 286 | |
| 287 void BytecodeGenerator::VisitCallRuntime(CallRuntime* node) { UNIMPLEMENTED(); } | |
| 288 | |
| 289 | |
| 290 void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* node) { | |
| 291 UNIMPLEMENTED(); | |
| 292 } | |
| 293 | |
| 294 | |
| 295 void BytecodeGenerator::VisitCountOperation(CountOperation* node) { | |
| 296 UNIMPLEMENTED(); | |
| 297 } | |
| 298 | |
| 299 | |
| 300 void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) { | |
| 301 switch (binop->op()) { | |
| 302 case Token::COMMA: | |
| 303 case Token::OR: | |
| 304 case Token::AND: | |
| 305 UNIMPLEMENTED(); | |
| 306 break; | |
| 307 default: | |
| 308 VisitArithmeticExpression(binop); | |
| 309 break; | |
| 310 } | |
| 311 } | |
| 312 | |
| 313 | |
| 314 void BytecodeGenerator::VisitCompareOperation(CompareOperation* node) { | |
| 315 UNIMPLEMENTED(); | |
| 316 } | |
| 317 | |
| 318 | |
| 319 void BytecodeGenerator::VisitSpread(Spread* node) { UNIMPLEMENTED(); } | |
| 320 | |
| 321 | |
| 322 void BytecodeGenerator::VisitThisFunction(ThisFunction* node) { | |
| 323 UNIMPLEMENTED(); | |
| 324 } | |
| 325 | |
| 326 | |
| 327 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* node) { | |
| 328 UNIMPLEMENTED(); | |
| 329 } | |
| 330 | |
| 331 | |
| 332 void BytecodeGenerator::VisitSuperPropertyReference( | |
| 333 SuperPropertyReference* node) { | |
| 334 UNIMPLEMENTED(); | |
| 335 } | |
| 336 | |
| 337 | |
| 338 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* binop) { | |
| 339 Token::Value op = binop->op(); | |
| 340 Expression* left = binop->left(); | |
| 341 Expression* right = binop->right(); | |
| 342 | |
| 343 TemporaryRegisterScope temporary_register_scope(&builder_); | |
| 344 Register temporary = temporary_register_scope.NewRegister(); | |
| 345 | |
| 346 Visit(left); | |
| 347 builder().StoreAccumulatorInRegister(temporary); | |
| 348 Visit(right); | |
| 349 builder().BinaryOperation(op, temporary); | |
| 350 } | |
| 351 | |
| 352 } // namespace interpreter | |
| 353 } // namespace internal | |
| 354 } // namespace v8 | |
| OLD | NEW |