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_stack_slots(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. |
| 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()); |
| 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); |
| 240 builder().LoadAccumulatorWithRegister(variable->index()); |
| 241 } |
| 242 |
| 243 |
| 244 void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
| 245 DCHECK(expr->target()->IsValidReferenceExpression()); |
| 246 |
| 247 // Left-hand side can only be a property, a global or a variable slot. |
| 248 Property* property = expr->target()->AsProperty(); |
| 249 LhsKind assign_type = Property::GetAssignType(property); |
| 250 int target_register = 0; |
| 251 switch (assign_type) { |
| 252 case VARIABLE: { |
| 253 Variable* variable = expr->target()->AsVariableProxy()->var(); |
| 254 target_register = variable->index(); |
| 255 DCHECK(variable->location() == VariableLocation::LOCAL); |
| 256 break; |
| 257 } |
| 258 case NAMED_PROPERTY: |
| 259 case KEYED_PROPERTY: |
| 260 case NAMED_SUPER_PROPERTY: |
| 261 case KEYED_SUPER_PROPERTY: |
| 262 UNIMPLEMENTED(); |
| 263 } |
| 264 |
| 265 DCHECK(!expr->is_compound()); |
| 266 Visit(expr->value()); |
| 267 builder().StoreAccumulatorInRegister(target_register); |
| 268 } |
| 269 |
| 270 |
| 271 void BytecodeGenerator::VisitYield(Yield* node) { UNIMPLEMENTED(); } |
| 272 |
| 273 |
| 274 void BytecodeGenerator::VisitThrow(Throw* node) { UNIMPLEMENTED(); } |
| 275 |
| 276 |
| 277 void BytecodeGenerator::VisitProperty(Property* node) { UNIMPLEMENTED(); } |
| 278 |
| 279 |
| 280 void BytecodeGenerator::VisitCall(Call* node) { UNIMPLEMENTED(); } |
| 281 |
| 282 |
| 283 void BytecodeGenerator::VisitCallNew(CallNew* node) { UNIMPLEMENTED(); } |
| 284 |
| 285 |
| 286 void BytecodeGenerator::VisitCallRuntime(CallRuntime* node) { UNIMPLEMENTED(); } |
| 287 |
| 288 |
| 289 void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* node) { |
| 290 UNIMPLEMENTED(); |
| 291 } |
| 292 |
| 293 |
| 294 void BytecodeGenerator::VisitCountOperation(CountOperation* node) { |
| 295 UNIMPLEMENTED(); |
| 296 } |
| 297 |
| 298 |
| 299 void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) { |
| 300 switch (binop->op()) { |
| 301 case Token::COMMA: |
| 302 case Token::OR: |
| 303 case Token::AND: |
| 304 UNIMPLEMENTED(); |
| 305 break; |
| 306 default: |
| 307 VisitArithmeticExpression(binop); |
| 308 break; |
| 309 } |
| 310 } |
| 311 |
| 312 |
| 313 void BytecodeGenerator::VisitCompareOperation(CompareOperation* node) { |
| 314 UNIMPLEMENTED(); |
| 315 } |
| 316 |
| 317 |
| 318 void BytecodeGenerator::VisitSpread(Spread* node) { UNIMPLEMENTED(); } |
| 319 |
| 320 |
| 321 void BytecodeGenerator::VisitThisFunction(ThisFunction* node) { |
| 322 UNIMPLEMENTED(); |
| 323 } |
| 324 |
| 325 |
| 326 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* node) { |
| 327 UNIMPLEMENTED(); |
| 328 } |
| 329 |
| 330 |
| 331 void BytecodeGenerator::VisitSuperPropertyReference( |
| 332 SuperPropertyReference* node) { |
| 333 UNIMPLEMENTED(); |
| 334 } |
| 335 |
| 336 |
| 337 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* binop) { |
| 338 Token::Value op = binop->op(); |
| 339 Expression* left = binop->left(); |
| 340 Expression* right = binop->right(); |
| 341 |
| 342 int scratch = builder().AllocateScratchRegister(); |
| 343 Visit(left); |
| 344 builder().StoreAccumulatorInRegister(scratch); |
| 345 Visit(right); |
| 346 builder().BinaryOperation(op, scratch); |
| 347 builder().FreeScratchRegister(scratch); |
| 348 } |
| 349 |
| 350 } // namespace interpreter |
| 351 } // namespace internal |
| 352 } // namespace v8 |
OLD | NEW |