[Interpreter] Ensure that implicit return undefined is generated.
authorrmcilroy <rmcilroy@chromium.org>
Tue, 8 Sep 2015 15:02:44 +0000 (08:02 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 8 Sep 2015 15:02:58 +0000 (15:02 +0000)
When there is no explicit return we need to generate an implicit
return undefined.

BUG=v8:4280
LOG=N

Review URL: https://codereview.chromium.org/1308693014

Cr-Commit-Position: refs/heads/master@{#30639}

src/interpreter/bytecode-array-builder.cc
src/interpreter/bytecode-array-builder.h
src/interpreter/bytecode-generator.cc
test/cctest/interpreter/test-bytecode-generator.cc

index dba816d..415de59 100644 (file)
@@ -37,6 +37,14 @@ void BytecodeArrayBuilder::set_parameter_count(int number_of_parameters) {
 int BytecodeArrayBuilder::parameter_count() const { return parameter_count_; }
 
 
+bool BytecodeArrayBuilder::HasExplicitReturn() {
+  // TODO(rmcilroy): When we have control flow we should return false here if
+  // there is an outstanding jump target, even if the last bytecode is kReturn.
+  return !bytecodes_.empty() &&
+         bytecodes_.back() == Bytecodes::ToByte(Bytecode::kReturn);
+}
+
+
 Register BytecodeArrayBuilder::Parameter(int parameter_index) {
   DCHECK_GE(parameter_index, 0);
   DCHECK_LT(parameter_index, parameter_count_);
index d4e1c34..a50c28b 100644 (file)
@@ -35,6 +35,9 @@ class BytecodeArrayBuilder {
   void set_locals_count(int number_of_locals);
   int locals_count() const;
 
+  // Returns true if the bytecode has an explicit return at the end.
+  bool HasExplicitReturn();
+
   Register Parameter(int parameter_index);
 
   // Constant loads to accumulator.
index 487b865..0f24995 100644 (file)
@@ -45,6 +45,13 @@ Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) {
   // Visit statements in the function body.
   VisitStatements(info->literal()->body());
 
+  // If the last bytecode wasn't a return, then return 'undefined' to avoid
+  // falling off the end.
+  if (!builder_.HasExplicitReturn()) {
+    builder_.LoadUndefined();
+    builder_.Return();
+  }
+
   set_scope(nullptr);
   set_info(nullptr);
   return builder_.ToBytecodeArray();
index c62e5ef..25a7148 100644 (file)
@@ -79,6 +79,7 @@ TEST(PrimitiveReturnStatements) {
   BytecodeGeneratorHelper helper;
 
   ExpectedSnippet<void*> snippets[] = {
+      {"", 0, 1, 2, {B(LdaUndefined), B(Return)}, 0},
       {"return;", 0, 1, 2, {B(LdaUndefined), B(Return)}, 0},
       {"return null;", 0, 1, 2, {B(LdaNull), B(Return)}, 0},
       {"return true;", 0, 1, 2, {B(LdaTrue), B(Return)}, 0},