OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
11 // with the distribution. | 11 // with the distribution. |
12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
15 // | 15 // |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 // Deprecated API entries use other deprecated entries, too. | |
29 #define V8_DISABLE_DEPRECATIONS 1 | |
30 | |
31 #include "api.h" | 28 #include "api.h" |
32 | 29 |
33 #include <math.h> // For isnan. | 30 #include <math.h> // For isnan. |
34 #include <string.h> // For memcpy, strlen. | 31 #include <string.h> // For memcpy, strlen. |
35 #include "../include/v8-debug.h" | 32 #include "../include/v8-debug.h" |
36 #include "../include/v8-profiler.h" | 33 #include "../include/v8-profiler.h" |
37 #include "../include/v8-testing.h" | 34 #include "../include/v8-testing.h" |
38 #include "bootstrapper.h" | 35 #include "bootstrapper.h" |
39 #include "code-stubs.h" | 36 #include "code-stubs.h" |
40 #include "compiler.h" | 37 #include "compiler.h" |
(...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 } | 782 } |
786 | 783 |
787 // Content of 'last_context' could be NULL. | 784 // Content of 'last_context' could be NULL. |
788 i::Context* last_context = | 785 i::Context* last_context = |
789 isolate->handle_scope_implementer()->RestoreContext(); | 786 isolate->handle_scope_implementer()->RestoreContext(); |
790 isolate->set_context(last_context); | 787 isolate->set_context(last_context); |
791 isolate->set_context_exit_happened(true); | 788 isolate->set_context_exit_happened(true); |
792 } | 789 } |
793 | 790 |
794 | 791 |
795 static void* DecodeSmiToAligned(i::Object* value, const char* location) { | 792 void Context::SetData(v8::Handle<Value> data) { |
796 ApiCheck(value->IsSmi(), location, "Not a Smi"); | 793 i::Handle<i::Context> env = Utils::OpenHandle(this); |
797 return reinterpret_cast<void*>(value); | 794 i::Isolate* isolate = env->GetIsolate(); |
| 795 if (IsDeadCheck(isolate, "v8::Context::SetData()")) return; |
| 796 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data); |
| 797 ASSERT(env->IsNativeContext()); |
| 798 if (env->IsNativeContext()) { |
| 799 env->set_data(*raw_data); |
| 800 } |
798 } | 801 } |
799 | 802 |
800 | 803 |
801 static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) { | 804 v8::Local<v8::Value> Context::GetData() { |
802 i::Smi* smi = reinterpret_cast<i::Smi*>(value); | 805 i::Handle<i::Context> env = Utils::OpenHandle(this); |
803 ApiCheck(smi->IsSmi(), location, "Pointer is not aligned"); | 806 i::Isolate* isolate = env->GetIsolate(); |
804 return smi; | 807 if (IsDeadCheck(isolate, "v8::Context::GetData()")) { |
805 } | 808 return Local<Value>(); |
806 | |
807 | |
808 static i::Handle<i::FixedArray> EmbedderDataFor(Context* context, | |
809 int index, | |
810 bool can_grow, | |
811 const char* location) { | |
812 i::Handle<i::Context> env = Utils::OpenHandle(context); | |
813 bool ok = !IsDeadCheck(env->GetIsolate(), location) && | |
814 ApiCheck(env->IsNativeContext(), location, "Not a native context") && | |
815 ApiCheck(index >= 0, location, "Negative index"); | |
816 if (!ok) return i::Handle<i::FixedArray>(); | |
817 i::Handle<i::FixedArray> data(env->embedder_data()); | |
818 if (index < data->length()) return data; | |
819 if (!can_grow) { | |
820 Utils::ReportApiFailure(location, "Index too large"); | |
821 return i::Handle<i::FixedArray>(); | |
822 } | 809 } |
823 int new_size = i::Max(index, data->length() << 1) + 1; | 810 ASSERT(env->IsNativeContext()); |
824 data = env->GetIsolate()->factory()->CopySizeFixedArray(data, new_size); | 811 if (!env->IsNativeContext()) { |
825 env->set_embedder_data(*data); | 812 return Local<Value>(); |
826 return data; | 813 } |
827 } | 814 i::Handle<i::Object> result(env->data(), isolate); |
828 | |
829 | |
830 v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) { | |
831 const char* location = "v8::Context::GetEmbedderData()"; | |
832 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location); | |
833 if (data.is_null()) return Local<Value>(); | |
834 i::Handle<i::Object> result(data->get(index), data->GetIsolate()); | |
835 return Utils::ToLocal(result); | 815 return Utils::ToLocal(result); |
836 } | 816 } |
837 | 817 |
838 | 818 |
839 void Context::SetEmbedderData(int index, v8::Handle<Value> value) { | |
840 const char* location = "v8::Context::SetEmbedderData()"; | |
841 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location); | |
842 if (data.is_null()) return; | |
843 i::Handle<i::Object> val = Utils::OpenHandle(*value); | |
844 data->set(index, *val); | |
845 ASSERT_EQ(*Utils::OpenHandle(*value), | |
846 *Utils::OpenHandle(*GetEmbedderData(index))); | |
847 } | |
848 | |
849 | |
850 void* Context::SlowGetAlignedPointerFromEmbedderData(int index) { | |
851 const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()"; | |
852 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location); | |
853 if (data.is_null()) return NULL; | |
854 return DecodeSmiToAligned(data->get(index), location); | |
855 } | |
856 | |
857 | |
858 void Context::SetAlignedPointerInEmbedderData(int index, void* value) { | |
859 const char* location = "v8::Context::SetAlignedPointerInEmbedderData()"; | |
860 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location); | |
861 data->set(index, EncodeAlignedAsSmi(value, location)); | |
862 ASSERT_EQ(value, GetAlignedPointerFromEmbedderData(index)); | |
863 } | |
864 | |
865 | |
866 i::Object** v8::HandleScope::RawClose(i::Object** value) { | 819 i::Object** v8::HandleScope::RawClose(i::Object** value) { |
867 if (!ApiCheck(!is_closed_, | 820 if (!ApiCheck(!is_closed_, |
868 "v8::HandleScope::Close()", | 821 "v8::HandleScope::Close()", |
869 "Local scope has already been closed")) { | 822 "Local scope has already been closed")) { |
870 return 0; | 823 return 0; |
871 } | 824 } |
872 LOG_API(isolate_, "CloseHandleScope"); | 825 LOG_API(isolate_, "CloseHandleScope"); |
873 | 826 |
874 // Read the result before popping the handle block. | 827 // Read the result before popping the handle block. |
875 i::Object* result = NULL; | 828 i::Object* result = NULL; |
(...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2254 return false; | 2207 return false; |
2255 } | 2208 } |
2256 return Utils::OpenHandle(this)->IsBoolean(); | 2209 return Utils::OpenHandle(this)->IsBoolean(); |
2257 } | 2210 } |
2258 | 2211 |
2259 | 2212 |
2260 bool Value::IsExternal() const { | 2213 bool Value::IsExternal() const { |
2261 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) { | 2214 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) { |
2262 return false; | 2215 return false; |
2263 } | 2216 } |
2264 return Utils::OpenHandle(this)->IsExternal(); | 2217 return Utils::OpenHandle(this)->IsForeign(); |
2265 } | 2218 } |
2266 | 2219 |
2267 | 2220 |
2268 bool Value::IsInt32() const { | 2221 bool Value::IsInt32() const { |
2269 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false; | 2222 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false; |
2270 i::Handle<i::Object> obj = Utils::OpenHandle(this); | 2223 i::Handle<i::Object> obj = Utils::OpenHandle(this); |
2271 if (obj->IsSmi()) return true; | 2224 if (obj->IsSmi()) return true; |
2272 if (obj->IsNumber()) { | 2225 if (obj->IsNumber()) { |
2273 double value = obj->Number(); | 2226 double value = obj->Number(); |
2274 static const i::DoubleRepresentation minus_zero(-0.0); | 2227 static const i::DoubleRepresentation minus_zero(-0.0); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2483 EXCEPTION_PREAMBLE(isolate); | 2436 EXCEPTION_PREAMBLE(isolate); |
2484 num = i::Execution::ToInteger(obj, &has_pending_exception); | 2437 num = i::Execution::ToInteger(obj, &has_pending_exception); |
2485 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>()); | 2438 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>()); |
2486 } | 2439 } |
2487 return Local<Integer>(ToApi<Integer>(num)); | 2440 return Local<Integer>(ToApi<Integer>(num)); |
2488 } | 2441 } |
2489 | 2442 |
2490 | 2443 |
2491 void External::CheckCast(v8::Value* that) { | 2444 void External::CheckCast(v8::Value* that) { |
2492 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return; | 2445 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return; |
2493 ApiCheck(Utils::OpenHandle(that)->IsExternal(), | 2446 i::Handle<i::Object> obj = Utils::OpenHandle(that); |
| 2447 ApiCheck(obj->IsForeign(), |
2494 "v8::External::Cast()", | 2448 "v8::External::Cast()", |
2495 "Could not convert to external"); | 2449 "Could not convert to external"); |
2496 } | 2450 } |
2497 | 2451 |
2498 | 2452 |
2499 void v8::Object::CheckCast(Value* that) { | 2453 void v8::Object::CheckCast(Value* that) { |
2500 if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return; | 2454 if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return; |
2501 i::Handle<i::Object> obj = Utils::OpenHandle(that); | 2455 i::Handle<i::Object> obj = Utils::OpenHandle(that); |
2502 ApiCheck(obj->IsJSObject(), | 2456 ApiCheck(obj->IsJSObject(), |
2503 "v8::Object::Cast()", | 2457 "v8::Object::Cast()", |
(...skipping 1742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4246 | 4200 |
4247 int v8::Object::InternalFieldCount() { | 4201 int v8::Object::InternalFieldCount() { |
4248 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 4202 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
4249 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) { | 4203 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) { |
4250 return 0; | 4204 return 0; |
4251 } | 4205 } |
4252 return obj->GetInternalFieldCount(); | 4206 return obj->GetInternalFieldCount(); |
4253 } | 4207 } |
4254 | 4208 |
4255 | 4209 |
4256 static bool InternalFieldOK(i::Handle<i::JSObject> obj, | 4210 Local<Value> v8::Object::CheckedGetInternalField(int index) { |
4257 int index, | |
4258 const char* location) { | |
4259 return !IsDeadCheck(obj->GetIsolate(), location) && | |
4260 ApiCheck(index < obj->GetInternalFieldCount(), | |
4261 location, | |
4262 "Internal field out of bounds"); | |
4263 } | |
4264 | |
4265 | |
4266 Local<Value> v8::Object::SlowGetInternalField(int index) { | |
4267 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 4211 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
4268 const char* location = "v8::Object::GetInternalField()"; | 4212 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) { |
4269 if (!InternalFieldOK(obj, index, location)) return Local<Value>(); | 4213 return Local<Value>(); |
4270 i::Handle<i::Object> value(obj->GetInternalField(index), obj->GetIsolate()); | 4214 } |
4271 return Utils::ToLocal(value); | 4215 if (!ApiCheck(index < obj->GetInternalFieldCount(), |
| 4216 "v8::Object::GetInternalField()", |
| 4217 "Reading internal field out of bounds")) { |
| 4218 return Local<Value>(); |
| 4219 } |
| 4220 i::Handle<i::Object> value(obj->GetInternalField(index)); |
| 4221 Local<Value> result = Utils::ToLocal(value); |
| 4222 #ifdef DEBUG |
| 4223 Local<Value> unchecked = UncheckedGetInternalField(index); |
| 4224 ASSERT(unchecked.IsEmpty() || (unchecked == result)); |
| 4225 #endif |
| 4226 return result; |
4272 } | 4227 } |
4273 | 4228 |
4274 | 4229 |
4275 void v8::Object::SetInternalField(int index, v8::Handle<Value> value) { | 4230 void v8::Object::SetInternalField(int index, v8::Handle<Value> value) { |
4276 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 4231 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
4277 const char* location = "v8::Object::SetInternalField()"; | 4232 i::Isolate* isolate = obj->GetIsolate(); |
4278 if (!InternalFieldOK(obj, index, location)) return; | 4233 if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) { |
| 4234 return; |
| 4235 } |
| 4236 if (!ApiCheck(index < obj->GetInternalFieldCount(), |
| 4237 "v8::Object::SetInternalField()", |
| 4238 "Writing internal field out of bounds")) { |
| 4239 return; |
| 4240 } |
| 4241 ENTER_V8(isolate); |
4279 i::Handle<i::Object> val = Utils::OpenHandle(*value); | 4242 i::Handle<i::Object> val = Utils::OpenHandle(*value); |
4280 obj->SetInternalField(index, *val); | 4243 obj->SetInternalField(index, *val); |
4281 ASSERT_EQ(value, GetInternalField(index)); | |
4282 } | 4244 } |
4283 | 4245 |
4284 | 4246 |
4285 void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) { | 4247 static bool CanBeEncodedAsSmi(void* ptr) { |
4286 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 4248 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr); |
4287 const char* location = "v8::Object::GetAlignedPointerFromInternalField()"; | 4249 return ((address & i::kEncodablePointerMask) == 0); |
4288 if (!InternalFieldOK(obj, index, location)) return NULL; | |
4289 return DecodeSmiToAligned(obj->GetInternalField(index), location); | |
4290 } | 4250 } |
4291 | 4251 |
4292 | 4252 |
4293 void v8::Object::SetAlignedPointerInInternalField(int index, void* value) { | 4253 static i::Smi* EncodeAsSmi(void* ptr) { |
4294 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 4254 ASSERT(CanBeEncodedAsSmi(ptr)); |
4295 const char* location = "v8::Object::SetAlignedPointerInInternalField()"; | 4255 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr); |
4296 if (!InternalFieldOK(obj, index, location)) return; | 4256 i::Smi* result = reinterpret_cast<i::Smi*>(address << i::kPointerToSmiShift); |
4297 obj->SetInternalField(index, EncodeAlignedAsSmi(value, location)); | 4257 ASSERT(i::Internals::HasSmiTag(result)); |
4298 ASSERT_EQ(value, GetAlignedPointerFromInternalField(index)); | 4258 ASSERT_EQ(result, i::Smi::FromInt(result->value())); |
| 4259 ASSERT_EQ(ptr, i::Internals::GetExternalPointerFromSmi(result)); |
| 4260 return result; |
4299 } | 4261 } |
4300 | 4262 |
4301 | 4263 |
4302 static void* ExternalValue(i::Object* obj) { | 4264 void v8::Object::SetPointerInInternalField(int index, void* value) { |
4303 // Obscure semantics for undefined, but somehow checked in our unit tests... | 4265 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); |
4304 if (obj->IsUndefined()) return NULL; | 4266 ENTER_V8(isolate); |
4305 i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0); | 4267 if (CanBeEncodedAsSmi(value)) { |
4306 return i::Foreign::cast(foreign)->foreign_address(); | 4268 Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value)); |
| 4269 } else { |
| 4270 HandleScope scope; |
| 4271 i::Handle<i::Foreign> foreign = |
| 4272 isolate->factory()->NewForeign( |
| 4273 reinterpret_cast<i::Address>(value), i::TENURED); |
| 4274 if (!foreign.is_null()) { |
| 4275 Utils::OpenHandle(this)->SetInternalField(index, *foreign); |
| 4276 } |
| 4277 } |
| 4278 ASSERT_EQ(value, GetPointerFromInternalField(index)); |
4307 } | 4279 } |
4308 | 4280 |
4309 | 4281 |
4310 void* Object::GetPointerFromInternalField(int index) { | |
4311 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | |
4312 const char* location = "v8::Object::GetPointerFromInternalField()"; | |
4313 if (!InternalFieldOK(obj, index, location)) return NULL; | |
4314 return ExternalValue(obj->GetInternalField(index)); | |
4315 } | |
4316 | |
4317 | |
4318 // --- E n v i r o n m e n t --- | 4282 // --- E n v i r o n m e n t --- |
4319 | 4283 |
4320 | 4284 |
4321 bool v8::V8::Initialize() { | 4285 bool v8::V8::Initialize() { |
4322 i::Isolate* isolate = i::Isolate::UncheckedCurrent(); | 4286 i::Isolate* isolate = i::Isolate::UncheckedCurrent(); |
4323 if (isolate != NULL && isolate->IsInitialized()) { | 4287 if (isolate != NULL && isolate->IsInitialized()) { |
4324 return true; | 4288 return true; |
4325 } | 4289 } |
4326 return InitializeHelper(); | 4290 return InitializeHelper(); |
4327 } | 4291 } |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4743 | 4707 |
4744 | 4708 |
4745 bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) { | 4709 bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) { |
4746 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()", | 4710 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()", |
4747 return false); | 4711 return false); |
4748 i::Object* obj = *Utils::OpenHandle(*value); | 4712 i::Object* obj = *Utils::OpenHandle(*value); |
4749 return obj->IsInstanceOf(*Utils::OpenHandle(this)); | 4713 return obj->IsInstanceOf(*Utils::OpenHandle(this)); |
4750 } | 4714 } |
4751 | 4715 |
4752 | 4716 |
4753 Local<External> v8::External::New(void* value) { | 4717 static Local<External> ExternalNewImpl(void* data) { |
4754 STATIC_ASSERT(sizeof(value) == sizeof(i::Address)); | 4718 return Utils::ToLocal(FACTORY->NewForeign(static_cast<i::Address>(data))); |
| 4719 } |
| 4720 |
| 4721 static void* ExternalValueImpl(i::Handle<i::Object> obj) { |
| 4722 return reinterpret_cast<void*>(i::Foreign::cast(*obj)->foreign_address()); |
| 4723 } |
| 4724 |
| 4725 |
| 4726 Local<Value> v8::External::Wrap(void* data) { |
| 4727 i::Isolate* isolate = i::Isolate::Current(); |
| 4728 STATIC_ASSERT(sizeof(data) == sizeof(i::Address)); |
| 4729 EnsureInitializedForIsolate(isolate, "v8::External::Wrap()"); |
| 4730 LOG_API(isolate, "External::Wrap"); |
| 4731 ENTER_V8(isolate); |
| 4732 |
| 4733 v8::Local<v8::Value> result = CanBeEncodedAsSmi(data) |
| 4734 ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data))) |
| 4735 : v8::Local<v8::Value>(ExternalNewImpl(data)); |
| 4736 |
| 4737 ASSERT_EQ(data, Unwrap(result)); |
| 4738 return result; |
| 4739 } |
| 4740 |
| 4741 |
| 4742 void* v8::Object::SlowGetPointerFromInternalField(int index) { |
| 4743 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
| 4744 i::Object* value = obj->GetInternalField(index); |
| 4745 if (value->IsSmi()) { |
| 4746 return i::Internals::GetExternalPointerFromSmi(value); |
| 4747 } else if (value->IsForeign()) { |
| 4748 return reinterpret_cast<void*>(i::Foreign::cast(value)->foreign_address()); |
| 4749 } else { |
| 4750 return NULL; |
| 4751 } |
| 4752 } |
| 4753 |
| 4754 |
| 4755 void* v8::External::FullUnwrap(v8::Handle<v8::Value> wrapper) { |
| 4756 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Unwrap()")) return 0; |
| 4757 i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper); |
| 4758 void* result; |
| 4759 if (obj->IsSmi()) { |
| 4760 result = i::Internals::GetExternalPointerFromSmi(*obj); |
| 4761 } else if (obj->IsForeign()) { |
| 4762 result = ExternalValueImpl(obj); |
| 4763 } else { |
| 4764 result = NULL; |
| 4765 } |
| 4766 ASSERT_EQ(result, QuickUnwrap(wrapper)); |
| 4767 return result; |
| 4768 } |
| 4769 |
| 4770 |
| 4771 Local<External> v8::External::New(void* data) { |
| 4772 STATIC_ASSERT(sizeof(data) == sizeof(i::Address)); |
4755 i::Isolate* isolate = i::Isolate::Current(); | 4773 i::Isolate* isolate = i::Isolate::Current(); |
4756 EnsureInitializedForIsolate(isolate, "v8::External::New()"); | 4774 EnsureInitializedForIsolate(isolate, "v8::External::New()"); |
4757 LOG_API(isolate, "External::New"); | 4775 LOG_API(isolate, "External::New"); |
4758 ENTER_V8(isolate); | 4776 ENTER_V8(isolate); |
4759 i::Handle<i::JSObject> external = isolate->factory()->NewExternal(value); | 4777 return ExternalNewImpl(data); |
4760 return Utils::ExternalToLocal(external); | |
4761 } | 4778 } |
4762 | 4779 |
4763 | 4780 |
4764 void* External::Value() const { | 4781 void* External::Value() const { |
4765 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return NULL; | 4782 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return 0; |
4766 return ExternalValue(*Utils::OpenHandle(this)); | 4783 i::Handle<i::Object> obj = Utils::OpenHandle(this); |
| 4784 return ExternalValueImpl(obj); |
4767 } | 4785 } |
4768 | 4786 |
4769 | 4787 |
4770 Local<String> v8::String::Empty() { | 4788 Local<String> v8::String::Empty() { |
4771 i::Isolate* isolate = i::Isolate::Current(); | 4789 i::Isolate* isolate = i::Isolate::Current(); |
4772 if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) { | 4790 if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) { |
4773 return v8::Local<String>(); | 4791 return v8::Local<String>(); |
4774 } | 4792 } |
4775 LOG_API(isolate, "String::Empty()"); | 4793 LOG_API(isolate, "String::Empty()"); |
4776 return Utils::ToLocal(isolate->factory()->empty_symbol()); | 4794 return Utils::ToLocal(isolate->factory()->empty_symbol()); |
(...skipping 1860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6637 | 6655 |
6638 v->VisitPointers(blocks_.first(), first_block_limit_); | 6656 v->VisitPointers(blocks_.first(), first_block_limit_); |
6639 | 6657 |
6640 for (int i = 1; i < blocks_.length(); i++) { | 6658 for (int i = 1; i < blocks_.length(); i++) { |
6641 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]); | 6659 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]); |
6642 } | 6660 } |
6643 } | 6661 } |
6644 | 6662 |
6645 | 6663 |
6646 } } // namespace v8::internal | 6664 } } // namespace v8::internal |
OLD | NEW |