| Index: test/cctest/test-api.cc | 
| diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc | 
| index 630391e93edaec3cfdfaeac3f24b8b042107ae53..7bbc1c1d1d9a19ee28a241718bd70b3f53e0e0e0 100644 | 
| --- a/test/cctest/test-api.cc | 
| +++ b/test/cctest/test-api.cc | 
| @@ -2765,6 +2765,136 @@ THREADED_TEST(ArrayBuffer_NeuteringScript) { | 
| } | 
|  | 
|  | 
| +class ScopedSharedArrayBufferContents { | 
| + public: | 
| +  explicit ScopedSharedArrayBufferContents( | 
| +      const v8::SharedArrayBuffer::Contents& contents) | 
| +      : contents_(contents) {} | 
| +  ~ScopedSharedArrayBufferContents() { free(contents_.Data()); } | 
| +  void* Data() const { return contents_.Data(); } | 
| +  size_t ByteLength() const { return contents_.ByteLength(); } | 
| + | 
| + private: | 
| +  const v8::SharedArrayBuffer::Contents contents_; | 
| +}; | 
| + | 
| + | 
| +THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) { | 
| +  i::FLAG_harmony_sharedarraybuffer = true; | 
| +  LocalContext env; | 
| +  v8::Isolate* isolate = env->GetIsolate(); | 
| +  v8::HandleScope handle_scope(isolate); | 
| + | 
| +  Local<v8::SharedArrayBuffer> ab = v8::SharedArrayBuffer::New(isolate, 1024); | 
| +  CheckInternalFieldsAreZero(ab); | 
| +  CHECK_EQ(1024, static_cast<int>(ab->ByteLength())); | 
| +  CHECK(!ab->IsExternal()); | 
| +  CcTest::heap()->CollectAllGarbage(); | 
| + | 
| +  ScopedSharedArrayBufferContents ab_contents(ab->Externalize()); | 
| +  CHECK(ab->IsExternal()); | 
| + | 
| +  CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); | 
| +  uint8_t* data = static_cast<uint8_t*>(ab_contents.Data()); | 
| +  DCHECK(data != NULL); | 
| +  env->Global()->Set(v8_str("ab"), ab); | 
| + | 
| +  v8::Handle<v8::Value> result = CompileRun("ab.byteLength"); | 
| +  CHECK_EQ(1024, result->Int32Value()); | 
| + | 
| +  result = CompileRun( | 
| +      "var u8 = new Uint8Array(ab);" | 
| +      "u8[0] = 0xFF;" | 
| +      "u8[1] = 0xAA;" | 
| +      "u8.length"); | 
| +  CHECK_EQ(1024, result->Int32Value()); | 
| +  CHECK_EQ(0xFF, data[0]); | 
| +  CHECK_EQ(0xAA, data[1]); | 
| +  data[0] = 0xCC; | 
| +  data[1] = 0x11; | 
| +  result = CompileRun("u8[0] + u8[1]"); | 
| +  CHECK_EQ(0xDD, result->Int32Value()); | 
| +} | 
| + | 
| + | 
| +THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) { | 
| +  i::FLAG_harmony_sharedarraybuffer = true; | 
| +  LocalContext env; | 
| +  v8::Isolate* isolate = env->GetIsolate(); | 
| +  v8::HandleScope handle_scope(isolate); | 
| + | 
| + | 
| +  v8::Local<v8::Value> result = CompileRun( | 
| +      "var ab1 = new SharedArrayBuffer(2);" | 
| +      "var u8_a = new Uint8Array(ab1);" | 
| +      "u8_a[0] = 0xAA;" | 
| +      "u8_a[1] = 0xFF; u8_a.buffer"); | 
| +  Local<v8::SharedArrayBuffer> ab1 = Local<v8::SharedArrayBuffer>::Cast(result); | 
| +  CheckInternalFieldsAreZero(ab1); | 
| +  CHECK_EQ(2, static_cast<int>(ab1->ByteLength())); | 
| +  CHECK(!ab1->IsExternal()); | 
| +  ScopedSharedArrayBufferContents ab1_contents(ab1->Externalize()); | 
| +  CHECK(ab1->IsExternal()); | 
| + | 
| +  result = CompileRun("ab1.byteLength"); | 
| +  CHECK_EQ(2, result->Int32Value()); | 
| +  result = CompileRun("u8_a[0]"); | 
| +  CHECK_EQ(0xAA, result->Int32Value()); | 
| +  result = CompileRun("u8_a[1]"); | 
| +  CHECK_EQ(0xFF, result->Int32Value()); | 
| +  result = CompileRun( | 
| +      "var u8_b = new Uint8Array(ab1);" | 
| +      "u8_b[0] = 0xBB;" | 
| +      "u8_a[0]"); | 
| +  CHECK_EQ(0xBB, result->Int32Value()); | 
| +  result = CompileRun("u8_b[1]"); | 
| +  CHECK_EQ(0xFF, result->Int32Value()); | 
| + | 
| +  CHECK_EQ(2, static_cast<int>(ab1_contents.ByteLength())); | 
| +  uint8_t* ab1_data = static_cast<uint8_t*>(ab1_contents.Data()); | 
| +  CHECK_EQ(0xBB, ab1_data[0]); | 
| +  CHECK_EQ(0xFF, ab1_data[1]); | 
| +  ab1_data[0] = 0xCC; | 
| +  ab1_data[1] = 0x11; | 
| +  result = CompileRun("u8_a[0] + u8_a[1]"); | 
| +  CHECK_EQ(0xDD, result->Int32Value()); | 
| +} | 
| + | 
| + | 
| +THREADED_TEST(SharedArrayBuffer_External) { | 
| +  i::FLAG_harmony_sharedarraybuffer = true; | 
| +  LocalContext env; | 
| +  v8::Isolate* isolate = env->GetIsolate(); | 
| +  v8::HandleScope handle_scope(isolate); | 
| + | 
| +  i::ScopedVector<uint8_t> my_data(100); | 
| +  memset(my_data.start(), 0, 100); | 
| +  Local<v8::SharedArrayBuffer> ab3 = | 
| +      v8::SharedArrayBuffer::New(isolate, my_data.start(), 100); | 
| +  CheckInternalFieldsAreZero(ab3); | 
| +  CHECK_EQ(100, static_cast<int>(ab3->ByteLength())); | 
| +  CHECK(ab3->IsExternal()); | 
| + | 
| +  env->Global()->Set(v8_str("ab3"), ab3); | 
| + | 
| +  v8::Handle<v8::Value> result = CompileRun("ab3.byteLength"); | 
| +  CHECK_EQ(100, result->Int32Value()); | 
| + | 
| +  result = CompileRun( | 
| +      "var u8_b = new Uint8Array(ab3);" | 
| +      "u8_b[0] = 0xBB;" | 
| +      "u8_b[1] = 0xCC;" | 
| +      "u8_b.length"); | 
| +  CHECK_EQ(100, result->Int32Value()); | 
| +  CHECK_EQ(0xBB, my_data[0]); | 
| +  CHECK_EQ(0xCC, my_data[1]); | 
| +  my_data[0] = 0xCC; | 
| +  my_data[1] = 0x11; | 
| +  result = CompileRun("u8_b[0] + u8_b[1]"); | 
| +  CHECK_EQ(0xDD, result->Int32Value()); | 
| +} | 
| + | 
| + | 
| THREADED_TEST(HiddenProperties) { | 
| LocalContext env; | 
| v8::Isolate* isolate = env->GetIsolate(); | 
|  |