OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #include "codegen.h" | 30 #include "codegen.h" |
31 #include "compiler.h" | 31 #include "compiler.h" |
32 #include "debug.h" | 32 #include "debug.h" |
33 #include "full-codegen.h" | 33 #include "full-codegen.h" |
34 #include "liveedit.h" | 34 #include "liveedit.h" |
35 #include "macro-assembler.h" | 35 #include "macro-assembler.h" |
36 #include "prettyprinter.h" | 36 #include "prettyprinter.h" |
37 #include "scopes.h" | 37 #include "scopes.h" |
| 38 #include "scopeinfo.h" |
38 #include "stub-cache.h" | 39 #include "stub-cache.h" |
39 | 40 |
40 namespace v8 { | 41 namespace v8 { |
41 namespace internal { | 42 namespace internal { |
42 | 43 |
43 void BreakableStatementChecker::Check(Statement* stmt) { | 44 void BreakableStatementChecker::Check(Statement* stmt) { |
44 Visit(stmt); | 45 Visit(stmt); |
45 } | 46 } |
46 | 47 |
47 | 48 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 void BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) { | 84 void BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) { |
84 } | 85 } |
85 | 86 |
86 | 87 |
87 void BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) { | 88 void BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) { |
88 // Return is breakable if the expression is. | 89 // Return is breakable if the expression is. |
89 Visit(stmt->expression()); | 90 Visit(stmt->expression()); |
90 } | 91 } |
91 | 92 |
92 | 93 |
93 void BreakableStatementChecker::VisitEnterWithContextStatement( | 94 void BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) { |
94 EnterWithContextStatement* stmt) { | |
95 Visit(stmt->expression()); | 95 Visit(stmt->expression()); |
96 } | 96 } |
97 | 97 |
98 | 98 |
99 void BreakableStatementChecker::VisitExitContextStatement( | 99 void BreakableStatementChecker::VisitExitContextStatement( |
100 ExitContextStatement* stmt) { | 100 ExitContextStatement* stmt) { |
101 } | 101 } |
102 | 102 |
103 | 103 |
104 void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) { | 104 void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) { |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 #endif | 310 #endif |
311 return !code.is_null(); | 311 return !code.is_null(); |
312 } | 312 } |
313 | 313 |
314 | 314 |
315 unsigned FullCodeGenerator::EmitStackCheckTable() { | 315 unsigned FullCodeGenerator::EmitStackCheckTable() { |
316 // The stack check table consists of a length (in number of entries) | 316 // The stack check table consists of a length (in number of entries) |
317 // field, and then a sequence of entries. Each entry is a pair of AST id | 317 // field, and then a sequence of entries. Each entry is a pair of AST id |
318 // and code-relative pc offset. | 318 // and code-relative pc offset. |
319 masm()->Align(kIntSize); | 319 masm()->Align(kIntSize); |
320 masm()->RecordComment("[ Stack check table"); | |
321 unsigned offset = masm()->pc_offset(); | 320 unsigned offset = masm()->pc_offset(); |
322 unsigned length = stack_checks_.length(); | 321 unsigned length = stack_checks_.length(); |
323 __ dd(length); | 322 __ dd(length); |
324 for (unsigned i = 0; i < length; ++i) { | 323 for (unsigned i = 0; i < length; ++i) { |
325 __ dd(stack_checks_[i].id); | 324 __ dd(stack_checks_[i].id); |
326 __ dd(stack_checks_[i].pc_and_state); | 325 __ dd(stack_checks_[i].pc_and_state); |
327 } | 326 } |
328 masm()->RecordComment("]"); | |
329 return offset; | 327 return offset; |
330 } | 328 } |
331 | 329 |
332 | 330 |
333 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) { | 331 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) { |
334 // Fill in the deoptimization information. | 332 // Fill in the deoptimization information. |
335 ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty()); | 333 ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty()); |
336 if (!info_->HasDeoptimizationSupport()) return; | 334 if (!info_->HasDeoptimizationSupport()) return; |
337 int length = bailout_entries_.length(); | 335 int length = bailout_entries_.length(); |
338 Handle<DeoptimizationOutputData> data = | 336 Handle<DeoptimizationOutputData> data = |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
840 ASSERT(forward_bailout_pending_ == NULL); | 838 ASSERT(forward_bailout_pending_ == NULL); |
841 } | 839 } |
842 } | 840 } |
843 | 841 |
844 | 842 |
845 void FullCodeGenerator::VisitBlock(Block* stmt) { | 843 void FullCodeGenerator::VisitBlock(Block* stmt) { |
846 Comment cmnt(masm_, "[ Block"); | 844 Comment cmnt(masm_, "[ Block"); |
847 Breakable nested_statement(this, stmt); | 845 Breakable nested_statement(this, stmt); |
848 SetStatementPosition(stmt); | 846 SetStatementPosition(stmt); |
849 | 847 |
| 848 Scope* saved_scope = scope(); |
| 849 if (stmt->block_scope() != NULL) { |
| 850 { Comment cmnt(masm_, "[ Extend block context"); |
| 851 scope_ = stmt->block_scope(); |
| 852 __ Push(scope_->GetSerializedScopeInfo()); |
| 853 PushFunctionArgumentForContextAllocation(); |
| 854 __ CallRuntime(Runtime::kPushBlockContext, 2); |
| 855 StoreToFrameField(StandardFrameConstants::kContextOffset, |
| 856 context_register()); |
| 857 } |
| 858 { Comment cmnt(masm_, "[ Declarations"); |
| 859 VisitDeclarations(scope_->declarations()); |
| 860 } |
| 861 } |
850 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); | 862 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); |
851 VisitStatements(stmt->statements()); | 863 VisitStatements(stmt->statements()); |
| 864 scope_ = saved_scope; |
852 __ bind(nested_statement.break_target()); | 865 __ bind(nested_statement.break_target()); |
853 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 866 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
854 } | 867 } |
855 | 868 |
856 | 869 |
857 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { | 870 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { |
858 Comment cmnt(masm_, "[ ExpressionStatement"); | 871 Comment cmnt(masm_, "[ ExpressionStatement"); |
859 SetStatementPosition(stmt); | 872 SetStatementPosition(stmt); |
860 VisitForEffect(stmt->expression()); | 873 VisitForEffect(stmt->expression()); |
861 } | 874 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
893 __ bind(&done); | 906 __ bind(&done); |
894 PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS); | 907 PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS); |
895 } | 908 } |
896 | 909 |
897 | 910 |
898 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { | 911 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { |
899 Comment cmnt(masm_, "[ ContinueStatement"); | 912 Comment cmnt(masm_, "[ ContinueStatement"); |
900 SetStatementPosition(stmt); | 913 SetStatementPosition(stmt); |
901 NestedStatement* current = nesting_stack_; | 914 NestedStatement* current = nesting_stack_; |
902 int stack_depth = 0; | 915 int stack_depth = 0; |
| 916 int context_length = 0; |
903 // When continuing, we clobber the unpredictable value in the accumulator | 917 // When continuing, we clobber the unpredictable value in the accumulator |
904 // with one that's safe for GC. If we hit an exit from the try block of | 918 // with one that's safe for GC. If we hit an exit from the try block of |
905 // try...finally on our way out, we will unconditionally preserve the | 919 // try...finally on our way out, we will unconditionally preserve the |
906 // accumulator on the stack. | 920 // accumulator on the stack. |
907 ClearAccumulator(); | 921 ClearAccumulator(); |
908 while (!current->IsContinueTarget(stmt->target())) { | 922 while (!current->IsContinueTarget(stmt->target())) { |
909 stack_depth = current->Exit(stack_depth); | 923 current = current->Exit(&stack_depth, &context_length); |
910 current = current->outer(); | |
911 } | 924 } |
912 __ Drop(stack_depth); | 925 __ Drop(stack_depth); |
| 926 if (context_length > 0) { |
| 927 while (context_length > 0) { |
| 928 LoadContextField(context_register(), Context::PREVIOUS_INDEX); |
| 929 --context_length; |
| 930 } |
| 931 StoreToFrameField(StandardFrameConstants::kContextOffset, |
| 932 context_register()); |
| 933 } |
913 | 934 |
914 Iteration* loop = current->AsIteration(); | 935 Iteration* loop = current->AsIteration(); |
915 __ jmp(loop->continue_target()); | 936 __ jmp(loop->continue_target()); |
916 } | 937 } |
917 | 938 |
918 | 939 |
919 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { | 940 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { |
920 Comment cmnt(masm_, "[ BreakStatement"); | 941 Comment cmnt(masm_, "[ BreakStatement"); |
921 SetStatementPosition(stmt); | 942 SetStatementPosition(stmt); |
922 NestedStatement* current = nesting_stack_; | 943 NestedStatement* current = nesting_stack_; |
923 int stack_depth = 0; | 944 int stack_depth = 0; |
| 945 int context_length = 0; |
924 // When breaking, we clobber the unpredictable value in the accumulator | 946 // When breaking, we clobber the unpredictable value in the accumulator |
925 // with one that's safe for GC. If we hit an exit from the try block of | 947 // with one that's safe for GC. If we hit an exit from the try block of |
926 // try...finally on our way out, we will unconditionally preserve the | 948 // try...finally on our way out, we will unconditionally preserve the |
927 // accumulator on the stack. | 949 // accumulator on the stack. |
928 ClearAccumulator(); | 950 ClearAccumulator(); |
929 while (!current->IsBreakTarget(stmt->target())) { | 951 while (!current->IsBreakTarget(stmt->target())) { |
930 stack_depth = current->Exit(stack_depth); | 952 current = current->Exit(&stack_depth, &context_length); |
931 current = current->outer(); | |
932 } | 953 } |
933 __ Drop(stack_depth); | 954 __ Drop(stack_depth); |
| 955 if (context_length > 0) { |
| 956 while (context_length > 0) { |
| 957 LoadContextField(context_register(), Context::PREVIOUS_INDEX); |
| 958 --context_length; |
| 959 } |
| 960 StoreToFrameField(StandardFrameConstants::kContextOffset, |
| 961 context_register()); |
| 962 } |
934 | 963 |
935 Breakable* target = current->AsBreakable(); | 964 Breakable* target = current->AsBreakable(); |
936 __ jmp(target->break_target()); | 965 __ jmp(target->break_target()); |
937 } | 966 } |
938 | 967 |
939 | 968 |
940 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { | 969 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
941 Comment cmnt(masm_, "[ ReturnStatement"); | 970 Comment cmnt(masm_, "[ ReturnStatement"); |
942 SetStatementPosition(stmt); | 971 SetStatementPosition(stmt); |
943 Expression* expr = stmt->expression(); | 972 Expression* expr = stmt->expression(); |
944 VisitForAccumulatorValue(expr); | 973 VisitForAccumulatorValue(expr); |
945 | 974 |
946 // Exit all nested statements. | 975 // Exit all nested statements. |
947 NestedStatement* current = nesting_stack_; | 976 NestedStatement* current = nesting_stack_; |
948 int stack_depth = 0; | 977 int stack_depth = 0; |
| 978 int context_length = 0; |
949 while (current != NULL) { | 979 while (current != NULL) { |
950 stack_depth = current->Exit(stack_depth); | 980 current = current->Exit(&stack_depth, &context_length); |
951 current = current->outer(); | |
952 } | 981 } |
953 __ Drop(stack_depth); | 982 __ Drop(stack_depth); |
954 | 983 |
955 EmitReturnSequence(); | 984 EmitReturnSequence(); |
956 } | 985 } |
957 | 986 |
958 | 987 |
959 void FullCodeGenerator::VisitEnterWithContextStatement( | 988 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { |
960 EnterWithContextStatement* stmt) { | 989 Comment cmnt(masm_, "[ WithStatement"); |
961 Comment cmnt(masm_, "[ EnterWithContextStatement"); | |
962 SetStatementPosition(stmt); | 990 SetStatementPosition(stmt); |
963 | 991 |
964 VisitForStackValue(stmt->expression()); | 992 VisitForStackValue(stmt->expression()); |
965 PushFunctionArgumentForContextAllocation(); | 993 PushFunctionArgumentForContextAllocation(); |
966 __ CallRuntime(Runtime::kPushWithContext, 2); | 994 __ CallRuntime(Runtime::kPushWithContext, 2); |
967 decrement_stack_height(); | 995 decrement_stack_height(); |
968 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); | 996 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); |
| 997 |
| 998 { WithOrCatch body(this); |
| 999 Visit(stmt->statement()); |
| 1000 } |
| 1001 |
| 1002 // Pop context. |
| 1003 LoadContextField(context_register(), Context::PREVIOUS_INDEX); |
| 1004 // Update local stack frame context field. |
| 1005 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); |
969 } | 1006 } |
970 | 1007 |
971 | 1008 |
972 void FullCodeGenerator::VisitExitContextStatement(ExitContextStatement* stmt) { | 1009 void FullCodeGenerator::VisitExitContextStatement(ExitContextStatement* stmt) { |
973 Comment cmnt(masm_, "[ ExitContextStatement"); | 1010 Comment cmnt(masm_, "[ ExitContextStatement"); |
974 SetStatementPosition(stmt); | 1011 SetStatementPosition(stmt); |
975 | 1012 |
976 // Pop context. | 1013 // Pop context. |
977 LoadContextField(context_register(), Context::PREVIOUS_INDEX); | 1014 LoadContextField(context_register(), Context::PREVIOUS_INDEX); |
978 // Update local stack frame context field. | 1015 // Update local stack frame context field. |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 __ push(result_register()); | 1154 __ push(result_register()); |
1118 PushFunctionArgumentForContextAllocation(); | 1155 PushFunctionArgumentForContextAllocation(); |
1119 __ CallRuntime(Runtime::kPushCatchContext, 3); | 1156 __ CallRuntime(Runtime::kPushCatchContext, 3); |
1120 StoreToFrameField(StandardFrameConstants::kContextOffset, | 1157 StoreToFrameField(StandardFrameConstants::kContextOffset, |
1121 context_register()); | 1158 context_register()); |
1122 } | 1159 } |
1123 | 1160 |
1124 Scope* saved_scope = scope(); | 1161 Scope* saved_scope = scope(); |
1125 scope_ = stmt->scope(); | 1162 scope_ = stmt->scope(); |
1126 ASSERT(scope_->declarations()->is_empty()); | 1163 ASSERT(scope_->declarations()->is_empty()); |
1127 Visit(stmt->catch_block()); | 1164 { WithOrCatch body(this); |
| 1165 Visit(stmt->catch_block()); |
| 1166 } |
1128 scope_ = saved_scope; | 1167 scope_ = saved_scope; |
1129 __ jmp(&done); | 1168 __ jmp(&done); |
1130 | 1169 |
1131 // Try block code. Sets up the exception handler chain. | 1170 // Try block code. Sets up the exception handler chain. |
1132 __ bind(&try_handler_setup); | 1171 __ bind(&try_handler_setup); |
1133 { | 1172 { |
1134 TryCatch try_block(this, &catch_entry); | 1173 TryCatch try_block(this, &catch_entry); |
1135 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); | 1174 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); |
1136 increment_stack_height(StackHandlerConstants::kSize / kPointerSize); | 1175 increment_stack_height(StackHandlerConstants::kSize / kPointerSize); |
1137 Visit(stmt->try_block()); | 1176 Visit(stmt->try_block()); |
(...skipping 25 matching lines...) Expand all Loading... |
1163 // | 1202 // |
1164 // The finally block must assume a return address on top of the stack | 1203 // The finally block must assume a return address on top of the stack |
1165 // (or in the link register on ARM chips) and a value (return value or | 1204 // (or in the link register on ARM chips) and a value (return value or |
1166 // exception) in the result register (rax/eax/r0), both of which must | 1205 // exception) in the result register (rax/eax/r0), both of which must |
1167 // be preserved. The return address isn't GC-safe, so it should be | 1206 // be preserved. The return address isn't GC-safe, so it should be |
1168 // cooked before GC. | 1207 // cooked before GC. |
1169 Label finally_entry; | 1208 Label finally_entry; |
1170 Label try_handler_setup; | 1209 Label try_handler_setup; |
1171 const int original_stack_height = stack_height(); | 1210 const int original_stack_height = stack_height(); |
1172 const int finally_block_stack_height = original_stack_height + 2; | 1211 const int finally_block_stack_height = original_stack_height + 2; |
1173 const int try_block_stack_height = original_stack_height + 4; | 1212 const int try_block_stack_height = original_stack_height + 5; |
1174 STATIC_ASSERT(StackHandlerConstants::kSize / kPointerSize == 4); | 1213 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
1175 | 1214 |
1176 // Setup the try-handler chain. Use a call to | 1215 // Setup the try-handler chain. Use a call to |
1177 // Jump to try-handler setup and try-block code. Use call to put try-handler | 1216 // Jump to try-handler setup and try-block code. Use call to put try-handler |
1178 // address on stack. | 1217 // address on stack. |
1179 __ Call(&try_handler_setup); | 1218 __ Call(&try_handler_setup); |
1180 // Try handler code. Return address of call is pushed on handler stack. | 1219 // Try handler code. Return address of call is pushed on handler stack. |
1181 { | 1220 { |
1182 // This code is only executed during stack-handler traversal when an | 1221 // This code is only executed during stack-handler traversal when an |
1183 // exception is thrown. The execption is in the result register, which | 1222 // exception is thrown. The execption is in the result register, which |
1184 // is retained by the finally block. | 1223 // is retained by the finally block. |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1293 Comment cmnt(masm_, "[ Throw"); | 1332 Comment cmnt(masm_, "[ Throw"); |
1294 // Throw has no effect on the stack height or the current expression context. | 1333 // Throw has no effect on the stack height or the current expression context. |
1295 // Usually the expression context is null, because throw is a statement. | 1334 // Usually the expression context is null, because throw is a statement. |
1296 VisitForStackValue(expr->exception()); | 1335 VisitForStackValue(expr->exception()); |
1297 __ CallRuntime(Runtime::kThrow, 1); | 1336 __ CallRuntime(Runtime::kThrow, 1); |
1298 decrement_stack_height(); | 1337 decrement_stack_height(); |
1299 // Never returns here. | 1338 // Never returns here. |
1300 } | 1339 } |
1301 | 1340 |
1302 | 1341 |
1303 int FullCodeGenerator::TryFinally::Exit(int stack_depth) { | 1342 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit( |
| 1343 int* stack_depth, |
| 1344 int* context_length) { |
1304 // The macros used here must preserve the result register. | 1345 // The macros used here must preserve the result register. |
1305 __ Drop(stack_depth); | 1346 __ Drop(*stack_depth); |
1306 __ PopTryHandler(); | 1347 __ PopTryHandler(); |
| 1348 *stack_depth = 0; |
| 1349 |
| 1350 Register context = FullCodeGenerator::context_register(); |
| 1351 while (*context_length > 0) { |
| 1352 codegen_->LoadContextField(context, Context::PREVIOUS_INDEX); |
| 1353 --(*context_length); |
| 1354 } |
| 1355 |
1307 __ Call(finally_entry_); | 1356 __ Call(finally_entry_); |
1308 return 0; | 1357 return previous_; |
1309 } | 1358 } |
1310 | 1359 |
1311 | 1360 |
1312 int FullCodeGenerator::TryCatch::Exit(int stack_depth) { | 1361 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit( |
| 1362 int* stack_depth, |
| 1363 int* context_length) { |
1313 // The macros used here must preserve the result register. | 1364 // The macros used here must preserve the result register. |
1314 __ Drop(stack_depth); | 1365 __ Drop(*stack_depth); |
1315 __ PopTryHandler(); | 1366 __ PopTryHandler(); |
1316 return 0; | 1367 *stack_depth = 0; |
| 1368 return previous_; |
1317 } | 1369 } |
1318 | 1370 |
1319 | 1371 |
1320 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* compare, | 1372 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* compare, |
1321 Label* if_true, | 1373 Label* if_true, |
1322 Label* if_false, | 1374 Label* if_false, |
1323 Label* fall_through) { | 1375 Label* fall_through) { |
1324 Expression *expr; | 1376 Expression *expr; |
1325 Handle<String> check; | 1377 Handle<String> check; |
1326 if (compare->IsLiteralCompareTypeof(&expr, &check)) { | 1378 if (compare->IsLiteralCompareTypeof(&expr, &check)) { |
1327 EmitLiteralCompareTypeof(expr, check, if_true, if_false, fall_through); | 1379 EmitLiteralCompareTypeof(expr, check, if_true, if_false, fall_through); |
1328 return true; | 1380 return true; |
1329 } | 1381 } |
1330 | 1382 |
1331 if (compare->IsLiteralCompareUndefined(&expr)) { | 1383 if (compare->IsLiteralCompareUndefined(&expr)) { |
1332 EmitLiteralCompareUndefined(expr, if_true, if_false, fall_through); | 1384 EmitLiteralCompareUndefined(expr, if_true, if_false, fall_through); |
1333 return true; | 1385 return true; |
1334 } | 1386 } |
1335 | 1387 |
1336 return false; | 1388 return false; |
1337 } | 1389 } |
1338 | 1390 |
1339 | 1391 |
1340 #undef __ | 1392 #undef __ |
1341 | 1393 |
1342 | 1394 |
1343 } } // namespace v8::internal | 1395 } } // namespace v8::internal |
OLD | NEW |