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 |