Index: src/api.cc |
=================================================================== |
--- src/api.cc (revision 1567) |
+++ src/api.cc (working copy) |
@@ -1447,7 +1447,7 @@ |
External* External::Cast(v8::Value* that) { |
if (IsDeadCheck("v8::External::Cast()")) return 0; |
i::Handle<i::Object> obj = Utils::OpenHandle(that); |
- ApiCheck(obj->IsProxy(), |
+ ApiCheck(obj->IsProxy() || obj->IsSmi(), |
"v8::External::Cast()", |
"Could not convert to external"); |
return static_cast<External*>(that); |
@@ -2229,6 +2229,11 @@ |
void* External::Value() const { |
if (IsDeadCheck("v8::External::Value()")) return 0; |
i::Handle<i::Object> obj = Utils::OpenHandle(this); |
+ if (obj->IsSmi()) { |
+ // The external value was an aligned pointer. |
+ return reinterpret_cast<void*>( |
+ i::Smi::cast(*obj)->value() << kAlignedPointerShift); |
+ } |
return reinterpret_cast<void*>(i::Proxy::cast(*obj)->proxy()); |
} |
@@ -2467,8 +2472,13 @@ |
STATIC_ASSERT(sizeof(data) == sizeof(i::Address)); |
LOG_API("External::New"); |
EnsureInitialized("v8::External::New()"); |
- i::Handle<i::Proxy> obj = i::Factory::NewProxy(static_cast<i::Address>(data)); |
- return Utils::ToLocal(obj); |
+ if ((reinterpret_cast<intptr_t>(data) & kAlignedPointerMask) == 0) { |
+ STATIC_ASSERT(sizeof(uintptr_t) == sizeof(int)); |
+ uintptr_t data_ptr = reinterpret_cast<uintptr_t>(data); |
+ i::Handle<i::Smi> obj(i::Smi::FromInt(data_ptr >> kAlignedPointerShift)); |
+ return Utils::ToLocal(obj); |
+ } |
+ return Utils::ToLocal(i::Factory::NewProxy(static_cast<i::Address>(data))); |
} |