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 |