| Index: src/api.cc
|
| ===================================================================
|
| --- src/api.cc (revision 6311)
|
| +++ src/api.cc (working copy)
|
| @@ -3204,18 +3204,35 @@
|
| }
|
|
|
|
|
| +static bool CanBeEncodedAsSmi(void* ptr) {
|
| + const intptr_t address = reinterpret_cast<intptr_t>(ptr);
|
| + return ((address & i::kEncodablePointerMask) == 0);
|
| +}
|
| +
|
| +
|
| +static i::Smi* EncodeAsSmi(void* ptr) {
|
| + ASSERT(CanBeEncodedAsSmi(ptr));
|
| + const intptr_t address = reinterpret_cast<intptr_t>(ptr);
|
| + i::Smi* result = reinterpret_cast<i::Smi*>(address << i::kPointerToSmiShift);
|
| + ASSERT(i::Internals::HasSmiTag(result));
|
| + ASSERT_EQ(result, i::Smi::FromInt(result->value()));
|
| + ASSERT_EQ(ptr, i::Internals::GetExternalPointerFromSmi(result));
|
| + return result;
|
| +}
|
| +
|
| +
|
| void v8::Object::SetPointerInInternalField(int index, void* value) {
|
| ENTER_V8;
|
| - i::Object* as_object = reinterpret_cast<i::Object*>(value);
|
| - if (as_object->IsSmi()) {
|
| - Utils::OpenHandle(this)->SetInternalField(index, as_object);
|
| - return;
|
| + if (CanBeEncodedAsSmi(value)) {
|
| + Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value));
|
| + } else {
|
| + HandleScope scope;
|
| + i::Handle<i::Proxy> proxy =
|
| + i::Factory::NewProxy(reinterpret_cast<i::Address>(value), i::TENURED);
|
| + if (!proxy.is_null())
|
| + Utils::OpenHandle(this)->SetInternalField(index, *proxy);
|
| }
|
| - HandleScope scope;
|
| - i::Handle<i::Proxy> proxy =
|
| - i::Factory::NewProxy(reinterpret_cast<i::Address>(value), i::TENURED);
|
| - if (!proxy.is_null())
|
| - Utils::OpenHandle(this)->SetInternalField(index, *proxy);
|
| + ASSERT_EQ(value, GetPointerFromInternalField(index));
|
| }
|
|
|
|
|
| @@ -3494,11 +3511,13 @@
|
| LOG_API("External::Wrap");
|
| EnsureInitialized("v8::External::Wrap()");
|
| ENTER_V8;
|
| - i::Object* as_object = reinterpret_cast<i::Object*>(data);
|
| - if (as_object->IsSmi()) {
|
| - return Utils::ToLocal(i::Handle<i::Object>(as_object));
|
| - }
|
| - return ExternalNewImpl(data);
|
| +
|
| + v8::Local<v8::Value> result = CanBeEncodedAsSmi(data)
|
| + ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data)))
|
| + : v8::Local<v8::Value>(ExternalNewImpl(data));
|
| +
|
| + ASSERT_EQ(data, Unwrap(result));
|
| + return result;
|
| }
|
|
|
|
|
| @@ -3506,7 +3525,7 @@
|
| i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
|
| i::Object* value = obj->GetInternalField(index);
|
| if (value->IsSmi()) {
|
| - return value;
|
| + return i::Internals::GetExternalPointerFromSmi(value);
|
| } else if (value->IsProxy()) {
|
| return reinterpret_cast<void*>(i::Proxy::cast(value)->proxy());
|
| } else {
|
| @@ -3520,8 +3539,7 @@
|
| i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper);
|
| void* result;
|
| if (obj->IsSmi()) {
|
| - // The external value was an aligned pointer.
|
| - result = *obj;
|
| + result = i::Internals::GetExternalPointerFromSmi(*obj);
|
| } else if (obj->IsProxy()) {
|
| result = ExternalValueImpl(obj);
|
| } else {
|
|
|