Changed test-debug/ThreadedDebugging to be non-flaky (issue 96).

Fixed step-in handling for Function.prototype.apply and call in the debugger (issue 269).

Fixed v8::Object::DeleteHiddenValue to not bail out when there are no hidden properties.

Added workaround for crash bug, where external symbol table entries with deleted resources would lead to NPEs when looking up in the symbol table.



git-svn-id: http://v8.googlecode.com/svn/trunk@1692 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index 5433a70..888c140 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2009-04-11: Version 1.1.8
+
+        Changed test-debug/ThreadedDebugging to be non-flaky (issue 96).
+
+        Fixed step-in handling for Function.prototype.apply and call in 
+        the debugger (issue 269).
+
+        Fixed v8::Object::DeleteHiddenValue to not bail out when there
+        are no hidden properties.
+
+        Added workaround for crash bug, where external symbol table 
+        entries with deleted resources would lead to NPEs when looking
+        up in the symbol table.
+
+
 2009-04-07: Version 1.1.7
 
         Added support for easily importing additional environment
diff --git a/SConstruct b/SConstruct
index 9654ebd..01083cc 100644
--- a/SConstruct
+++ b/SConstruct
@@ -142,7 +142,7 @@
       'DIALECTFLAGS': ['/nologo'],
       'CCFLAGS':      ['$DIALECTFLAGS', '$WARNINGFLAGS'],
       'CXXFLAGS':     ['$CCFLAGS', '/GR-', '/Gy'],
-      'CPPDEFINES':   ['WIN32', '_USE_32BIT_TIME_T', 'PCRE_STATIC'],
+      'CPPDEFINES':   ['WIN32', '_USE_32BIT_TIME_T'],
       'LINKFLAGS':    ['/NOLOGO', '/MACHINE:X86', '/INCREMENTAL:NO',
           '/NXCOMPAT', '/IGNORE:4221'],
       'ARFLAGS':      ['/NOLOGO'],
diff --git a/src/api.cc b/src/api.cc
index 1ddb2c6..da674b2 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -2077,13 +2077,13 @@
   ON_BAILOUT("v8::DeleteHiddenValue()", return false);
   ENTER_V8;
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
-  i::Handle<i::JSObject> hidden_props(
-      i::JSObject::cast(*i::GetHiddenProperties(self, false)));
+  i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
   if (hidden_props->IsUndefined()) {
-    return false;
+    return true;
   }
+  i::Handle<i::JSObject> js_obj(i::JSObject::cast(*hidden_props));
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
-  return i::DeleteProperty(hidden_props, key_obj)->IsTrue();
+  return i::DeleteProperty(js_obj, key_obj)->IsTrue();
 }
 
 
@@ -2373,7 +2373,7 @@
 
 
 const char* v8::V8::GetVersion() {
-  return "1.1.7";
+  return "1.1.8";
 }
 
 
diff --git a/src/debug.cc b/src/debug.cc
index 4901f5f..1374c15 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -1160,7 +1160,31 @@
   if (fp == Debug::step_in_fp()) {
     // Don't allow step into functions in the native context.
     if (function->context()->global() != Top::context()->builtins()) {
-      Debug::FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
+      if (function->shared()->code() ==
+          Builtins::builtin(Builtins::FunctionApply) ||
+          function->shared()->code() ==
+          Builtins::builtin(Builtins::FunctionCall)) {
+        // Handle function.apply and function.call separately to flood the
+        // function to be called and not the code for Builtins::FunctionApply or
+        // Builtins::FunctionCall. At the point of the call IC to call either
+        // Builtins::FunctionApply or Builtins::FunctionCall the expression
+        // stack has the following content:
+        //   symbol "apply" or "call"
+        //   function apply or call was called on
+        //   receiver for apply or call (first parameter to apply or call)
+        //   ... further arguments to apply or call.
+        JavaScriptFrameIterator it;
+        ASSERT(it.frame()->fp() == fp);
+        ASSERT(it.frame()->GetExpression(1)->IsJSFunction());
+        if (it.frame()->GetExpression(1)->IsJSFunction()) {
+          Handle<JSFunction>
+              actual_function(JSFunction::cast(it.frame()->GetExpression(1)));
+          Handle<SharedFunctionInfo> actual_shared(actual_function->shared());
+          Debug::FloodWithOneShot(actual_shared);
+        }
+      } else {
+        Debug::FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
+      }
     }
   }
 }
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index b369cac..740864c 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -96,6 +96,24 @@
 }
 
 
+#ifdef DEBUG
+// Helper class for verifying the symbol table.
+class SymbolTableVerifier : public ObjectVisitor {
+ public:
+  SymbolTableVerifier() { }
+  void VisitPointers(Object** start, Object** end) {
+    // Visit all HeapObject pointers in [start, end).
+    for (Object** p = start; p < end; p++) {
+      if ((*p)->IsHeapObject()) {
+        // Check that the symbol is actually a symbol.
+        ASSERT((*p)->IsNull() || (*p)->IsUndefined() || (*p)->IsSymbol());
+      }
+    }
+  }
+};
+#endif  // DEBUG
+
+
 void MarkCompactCollector::Prepare(GCTracer* tracer) {
   // Rather than passing the tracer around we stash it in a static member
   // variable.
@@ -148,6 +166,10 @@
   }
 
 #ifdef DEBUG
+  SymbolTable* symbol_table = SymbolTable::cast(Heap::symbol_table());
+  SymbolTableVerifier v;
+  symbol_table->IterateElements(&v);
+
   live_bytes_ = 0;
   live_young_objects_ = 0;
   live_old_pointer_objects_ = 0;
diff --git a/src/objects.cc b/src/objects.cc
index 6806829..f9f869d 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -3301,6 +3301,13 @@
   }
   ASSERT(string_tag == kExternalStringTag);
   ExternalTwoByteString* ext = ExternalTwoByteString::cast(string);
+  // This is a workaround for Chromium bug 9746: http://crbug.com/9746
+  // For external strings with a deleted resource we return a special
+  // Vector which will not compare to any string when doing SymbolTable
+  // lookups.
+  if (ext->resource() == NULL) {
+    return Vector<const uc16>(NULL, length);
+  }
   const uc16* start =
       reinterpret_cast<const uc16*>(ext->resource()->data());
   return Vector<const uc16>(start + offset, length);
@@ -4117,6 +4124,18 @@
 }
 
 
+// This is a workaround for Chromium bug 9746: http://crbug.com/9746
+// Returns true if this Vector matches the problem exposed in the bug.
+template <typename T>
+static bool CheckVectorForBug9746(Vector<T> vec) {
+  // The problem is that somehow external string entries in the symbol
+  // table can have their resources collected while they are still in the
+  // table. This should not happen according to the test in the function
+  // DisposeExternalString in api.cc, but we have evidence that it does.
+  return (vec.start() == NULL) ? true : false;
+}
+
+
 static StringInputBuffer string_compare_buffer_b;
 
 
@@ -4127,7 +4146,9 @@
       VectorIterator<char> ib(b->ToAsciiVector());
       return CompareStringContents(ia, &ib);
     } else {
-      VectorIterator<uc16> ib(b->ToUC16Vector());
+      Vector<const uc16> vb = b->ToUC16Vector();
+      if (CheckVectorForBug9746(vb)) return false;
+      VectorIterator<uc16> ib(vb);
       return CompareStringContents(ia, &ib);
     }
   } else {
@@ -4169,7 +4190,9 @@
           return CompareRawStringContents(vec1, vec2);
         } else {
           VectorIterator<char> buf1(vec1);
-          VectorIterator<uc16> ib(other->ToUC16Vector());
+          Vector<const uc16> vec2 = other->ToUC16Vector();
+          if (CheckVectorForBug9746(vec2)) return false;
+          VectorIterator<uc16> ib(vec2);
           return CompareStringContents(&buf1, &ib);
         }
       } else {
@@ -4179,13 +4202,15 @@
       }
     } else {
       Vector<const uc16> vec1 = this->ToUC16Vector();
+      if (CheckVectorForBug9746(vec1)) return false;
       if (other->IsFlat()) {
         if (StringShape(other).IsAsciiRepresentation()) {
           VectorIterator<uc16> buf1(vec1);
           VectorIterator<char> ib(other->ToAsciiVector());
           return CompareStringContents(&buf1, &ib);
         } else {
-          Vector<const uc16> vec2(other->ToUC16Vector());
+          Vector<const uc16> vec2 = other->ToUC16Vector();
+          if (CheckVectorForBug9746(vec2)) return false;
           return CompareRawStringContents(vec1, vec2);
         }
       } else {
@@ -4230,6 +4255,18 @@
 
 
 bool String::IsEqualTo(Vector<const char> str) {
+  // This is a workaround for Chromium bug 9746: http://crbug.com/9746
+  // The problem is that somehow external string entries in the symbol
+  // table can have their resources deleted while they are still in the
+  // table. This should not happen according to the test in the function
+  // DisposeExternalString in api.cc but we have evidence that it does.
+  // Thus we add this bailout here.
+  StringShape shape(this);
+  if (shape.IsExternalTwoByte()) {
+    ExternalTwoByteString* ext = ExternalTwoByteString::cast(this);
+    if (ext->resource() == NULL) return false;
+  }
+
   int slen = length();
   Access<Scanner::Utf8Decoder> decoder(Scanner::utf8_decoder());
   decoder->Reset(str.start(), str.length());
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index 5bbc895..f9a5dea 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -552,9 +552,34 @@
 
 static Sampler* active_sampler_ = NULL;
 
+
+#if !defined(__GLIBC__) && (defined(__arm__) || defined(__thumb__))
+// Android runs a fairly new Linux kernel, so signal info is there,
+// but the C library doesn't have the structs defined.
+
+struct sigcontext {
+  uint32_t trap_no;
+  uint32_t error_code;
+  uint32_t oldmask;
+  uint32_t gregs[16];
+  uint32_t arm_cpsr;
+  uint32_t fault_address;
+};
+typedef uint32_t __sigset_t;
+typedef struct sigcontext mcontext_t;
+typedef struct ucontext {
+  uint32_t uc_flags;
+  struct ucontext *uc_link;
+  stack_t uc_stack;
+  mcontext_t uc_mcontext;
+  __sigset_t uc_sigmask;
+} ucontext_t;
+enum ArmRegisters {R15 = 15, R13 = 13, R11 = 11};
+
+#endif
+
+
 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
-  // Ucontext is a glibc extension - no profiling on Android at the moment.
-#ifdef __GLIBC__
   USE(info);
   if (signal != SIGPROF) return;
   if (active_sampler_ == NULL) return;
@@ -581,7 +606,6 @@
   sample.state = Logger::state();
 
   active_sampler_->Tick(&sample);
-#endif
 }
 
 
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index dd705d2..d899e8d 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -1293,6 +1293,9 @@
 
   i::Heap::CollectAllGarbage();
 
+  // Make sure delete of a non-existent hidden value works
+  CHECK(obj->DeleteHiddenValue(key));
+
   CHECK(obj->SetHiddenValue(key, v8::Integer::New(1503)));
   CHECK_EQ(1503, obj->GetHiddenValue(key)->Int32Value());
   CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002)));
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 74d590e..5926a8b 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -2406,6 +2406,96 @@
 }
 
 
+// Test that step in works with function.apply.
+TEST(DebugStepFunctionApply) {
+  v8::HandleScope scope;
+  DebugLocalContext env;
+
+  // Create a function for testing stepping.
+  v8::Local<v8::Function> foo = CompileFunction(
+      &env,
+      "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }"
+      "function foo(){ debugger; bar.apply(this, [1,2,3]); }",
+      "foo");
+
+  // Register a debug event listener which steps and counts.
+  v8::Debug::SetDebugEventListener(DebugEventStep);
+
+  step_action = StepIn;
+  break_point_hit_count = 0;
+  foo->Call(env->Global(), 0, NULL);
+
+  // With stepping all break locations are hit.
+  CHECK_EQ(6, break_point_hit_count);
+
+  v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
+
+  // Register a debug event listener which just counts.
+  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+
+  break_point_hit_count = 0;
+  foo->Call(env->Global(), 0, NULL);
+
+  // Without stepping only the debugger statement is hit.
+  CHECK_EQ(1, break_point_hit_count);
+
+  v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
+}
+
+
+// Test that step in works with function.call.
+TEST(DebugStepFunctionCall) {
+  v8::HandleScope scope;
+  DebugLocalContext env;
+
+  // Create a function for testing stepping.
+  v8::Local<v8::Function> foo = CompileFunction(
+      &env,
+      "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }"
+      "function foo(a){ debugger;"
+      "                 if (a) {"
+      "                   bar.call(this, 1, 2, 3);"
+      "                 } else {"
+      "                   bar.call(this, 0);"
+      "                 }"
+      "}",
+      "foo");
+
+  // Register a debug event listener which steps and counts.
+  v8::Debug::SetDebugEventListener(DebugEventStep);
+  step_action = StepIn;
+
+  // Check stepping where the if condition in bar is false.
+  break_point_hit_count = 0;
+  foo->Call(env->Global(), 0, NULL);
+  CHECK_EQ(4, break_point_hit_count);
+
+  // Check stepping where the if condition in bar is true.
+  break_point_hit_count = 0;
+  const int argc = 1;
+  v8::Handle<v8::Value> argv[argc] = { v8::True() };
+  foo->Call(env->Global(), argc, argv);
+  CHECK_EQ(6, break_point_hit_count);
+
+  v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
+
+  // Register a debug event listener which just counts.
+  v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+
+  break_point_hit_count = 0;
+  foo->Call(env->Global(), 0, NULL);
+
+  // Without stepping only the debugger statement is hit.
+  CHECK_EQ(1, break_point_hit_count);
+
+  v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
+}
+
+
 // Test break on exceptions. For each exception break combination the number
 // of debug event exception callbacks and message callbacks are collected. The
 // number of debug event exception callbacks are used to check that the
@@ -3300,6 +3390,12 @@
 };
 
 
+static v8::Handle<v8::Value> ThreadedAtBarrier1(const v8::Arguments& args) {
+  threaded_debugging_barriers.barrier_1.Wait();
+  return v8::Undefined();
+}
+
+
 static void ThreadedMessageHandler(const uint16_t* message, int length,
                                    void *data) {
   static char print_buffer[1000];
@@ -3313,7 +3409,7 @@
 
 
 void V8Thread::Run() {
-  const char* source_1 =
+  const char* source =
       "flag = true;\n"
       "function bar( new_value ) {\n"
       "  flag = new_value;\n"
@@ -3323,19 +3419,25 @@
       "function foo() {\n"
       "  var x = 1;\n"
       "  while ( flag == true ) {\n"
+      "    if ( x == 1 ) {\n"
+      "      ThreadedAtBarrier1();\n"
+      "    }\n"
       "    x = x + 1;\n"
       "  }\n"
       "}\n"
-      "\n";
-  const char* source_2 = "foo();\n";
+      "\n"
+      "foo();\n";
 
   v8::HandleScope scope;
   DebugLocalContext env;
   v8::Debug::SetMessageHandler(&ThreadedMessageHandler);
+  v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+  global_template->Set(v8::String::New("ThreadedAtBarrier1"),
+                       v8::FunctionTemplate::New(ThreadedAtBarrier1));
+  v8::Handle<v8::Context> context = v8::Context::New(NULL, global_template);
+  v8::Context::Scope context_scope(context);
 
-  CompileRun(source_1);
-  threaded_debugging_barriers.barrier_1.Wait();
-  CompileRun(source_2);
+  CompileRun(source);
 }
 
 void DebuggerThread::Run() {
diff --git a/test/cctest/test-strings.cc b/test/cctest/test-strings.cc
index b38d645..3be5d62 100644
--- a/test/cctest/test-strings.cc
+++ b/test/cctest/test-strings.cc
@@ -387,3 +387,60 @@
       CHECK_EQ(kNoChar, buffer[j]);
   }
 }
+
+
+class TwoByteResource: public v8::String::ExternalStringResource {
+ public:
+  explicit TwoByteResource(const uint16_t* data, size_t length)
+      : data_(data), length_(length) { }
+  virtual ~TwoByteResource() { }
+
+  const uint16_t* data() const { return data_; }
+  size_t length() const { return length_; }
+
+ private:
+  const uint16_t* data_;
+  size_t length_;
+};
+
+
+TEST(ExternalCrBug9746) {
+  InitializeVM();
+  v8::HandleScope handle_scope;
+
+  // This set of tests verifies that the workaround for Chromium bug 9746
+  // works correctly. In certain situations the external resource of a symbol
+  // is collected while the symbol is still part of the symbol table.
+  static uint16_t two_byte_data[] = {
+    't', 'w', 'o', '-', 'b', 'y', 't', 'e', ' ', 'd', 'a', 't', 'a'
+  };
+  static size_t two_byte_length =
+      sizeof(two_byte_data) / sizeof(two_byte_data[0]);
+  static const char* one_byte_data = "two-byte data";
+
+  // Allocate an external string resource and external string.
+  TwoByteResource* resource = new TwoByteResource(two_byte_data,
+                                                  two_byte_length);
+  Handle<String> string = Factory::NewExternalStringFromTwoByte(resource);
+  Vector<const char> one_byte_vec = CStrVector(one_byte_data);
+  Handle<String> compare = Factory::NewStringFromAscii(one_byte_vec);
+
+  // Verify the correct behaviour before "collecting" the external resource.
+  CHECK(string->IsEqualTo(one_byte_vec));
+  CHECK(string->Equals(*compare));
+
+  // "Collect" the external resource manually by setting the external resource
+  // pointer to NULL. Then redo the comparisons, they should not match AND
+  // not crash.
+  Handle<ExternalTwoByteString> external(ExternalTwoByteString::cast(*string));
+  external->set_resource(NULL);
+  CHECK_EQ(false, string->IsEqualTo(one_byte_vec));
+#if !defined(DEBUG)
+  // These tests only work in non-debug as there are ASSERTs in the code that
+  // do prevent the ability to even get into the broken code when running the
+  // debug version of V8.
+  CHECK_EQ(false, string->Equals(*compare));
+  CHECK_EQ(false, compare->Equals(*string));
+  CHECK_EQ(false, string->Equals(Heap::empty_string()));
+#endif  // !defined(DEBUG)
+}
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index 276f5a4..5a76078 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -36,9 +36,6 @@
 
 big-object-literal: PASS, SKIP if ($arch == arm)
 
-# Bug realiably triggers a debug assertion and crashed in release mode.
-bugs/bug-269: CRASH, FAIL if $mode == debug
-
 [ $arch == arm ]
 
 # Slow tests which times out in debug mode.
@@ -64,7 +61,7 @@
 debug-step: SKIP
 debug-breakpoints: PASS || FAIL
 debug-handle: CRASH, FAIL if $mode == debug
-bugs/bug-269: SKIP
+regress/regress-269: SKIP
 
 # Bug number 130 http://code.google.com/p/v8/issues/detail?id=130
 # Fails on real ARM hardware but not on the simulator.
diff --git a/test/mjsunit/bugs/bug-269.js b/test/mjsunit/regress/regress-269.js
similarity index 100%
rename from test/mjsunit/bugs/bug-269.js
rename to test/mjsunit/regress/regress-269.js
diff --git a/tools/presubmit.py b/tools/presubmit.py
index 27a3f2c..3e714de 100755
--- a/tools/presubmit.py
+++ b/tools/presubmit.py
@@ -35,6 +35,9 @@
 import sys
 import subprocess
 
+# Disabled LINT rules and reason.
+# build/include_what_you_use: Started giving false positives for variables
+#  named "string" and "map" assuming that you needed to include STL headers.
 
 ENABLED_LINT_RULES = """
 build/class
@@ -42,7 +45,6 @@
 build/endif_comment
 build/forward_decl
 build/include_order
-build/include_what_you_use
 build/printf_format
 build/storage_class
 legal/copyright
diff --git a/tools/v8.xcodeproj/project.pbxproj b/tools/v8.xcodeproj/project.pbxproj
index caa6b33..df84554 100644
--- a/tools/v8.xcodeproj/project.pbxproj
+++ b/tools/v8.xcodeproj/project.pbxproj
@@ -202,6 +202,7 @@
 		89F23C9E0E78D5FD006B2466 /* macro-assembler-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1540E719B8F00D62E90 /* macro-assembler-arm.cc */; };
 		89F23C9F0E78D604006B2466 /* simulator-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF17D0E719B8F00D62E90 /* simulator-arm.cc */; };
 		89F23CA00E78D609006B2466 /* stub-cache-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18A0E719B8F00D62E90 /* stub-cache-arm.cc */; };
+		89FB0E3A0F8E533F00B04B3C /* d8-posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89FB0E360F8E531900B04B3C /* d8-posix.cc */; };
 		9FC86ABD0F5FEDAC00F22668 /* oprofile-agent.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FC86ABB0F5FEDAC00F22668 /* oprofile-agent.cc */; };
 		9FC86ABE0F5FEDAC00F22668 /* oprofile-agent.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FC86ABB0F5FEDAC00F22668 /* oprofile-agent.cc */; };
 /* End PBXBuildFile section */
@@ -517,6 +518,8 @@
 		89B12E8D0E7FF2A40080BA62 /* presubmit.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = presubmit.py; sourceTree = "<group>"; };
 		89F23C870E78D5B2006B2466 /* libv8-arm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libv8-arm.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		89F23C950E78D5B6006B2466 /* v8_shell-arm */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "v8_shell-arm"; sourceTree = BUILT_PRODUCTS_DIR; };
+		89FB0E360F8E531900B04B3C /* d8-posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "d8-posix.cc"; path = "../src/d8-posix.cc"; sourceTree = "<group>"; };
+		89FB0E370F8E531900B04B3C /* d8-windows.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "d8-windows.cc"; path = "../src/d8-windows.cc"; sourceTree = "<group>"; };
 		9FC86ABB0F5FEDAC00F22668 /* oprofile-agent.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "oprofile-agent.cc"; sourceTree = "<group>"; };
 		9FC86ABC0F5FEDAC00F22668 /* oprofile-agent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "oprofile-agent.h"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
@@ -872,6 +875,8 @@
 				89A15C910EE46A1700B48DEB /* d8-readline.cc */,
 				893988150F2A3686007D5254 /* d8-debug.cc */,
 				893A72320F7B4AD700303DD2 /* d8-debug.h */,
+				89FB0E360F8E531900B04B3C /* d8-posix.cc */,
+				89FB0E370F8E531900B04B3C /* d8-windows.cc */,
 				89A15C920EE46A1700B48DEB /* d8.cc */,
 				89A15C930EE46A1700B48DEB /* d8.h */,
 				89A15C940EE46A1700B48DEB /* d8.js */,
@@ -1073,6 +1078,7 @@
 				8939880D0F2A362A007D5254 /* d8.cc in Sources */,
 				893988160F2A3688007D5254 /* d8-debug.cc in Sources */,
 				893988330F2A3B8F007D5254 /* d8-js.cc in Sources */,
+				89FB0E3A0F8E533F00B04B3C /* d8-posix.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/tools/visual_studio/common.vsprops b/tools/visual_studio/common.vsprops
index 7e18f17..f131a4a 100644
--- a/tools/visual_studio/common.vsprops
+++ b/tools/visual_studio/common.vsprops
@@ -10,7 +10,7 @@
 	<Tool
 		Name="VCCLCompilerTool"
 		AdditionalIncludeDirectories="$(ProjectDir)\..\..\src;$(IntDir)\DerivedSources"
-		PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;_HAS_EXCEPTIONS=0;PCRE_STATIC;ENABLE_LOGGING_AND_PROFILING"
+		PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;_HAS_EXCEPTIONS=0;ENABLE_LOGGING_AND_PROFILING"
 		MinimalRebuild="false"
 		ExceptionHandling="0"
 		RuntimeTypeInfo="false"