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 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
806 } | 803 } |
807 | 804 |
808 // Content of 'last_context' could be NULL. | 805 // Content of 'last_context' could be NULL. |
809 i::Context* last_context = | 806 i::Context* last_context = |
810 isolate->handle_scope_implementer()->RestoreContext(); | 807 isolate->handle_scope_implementer()->RestoreContext(); |
811 isolate->set_context(last_context); | 808 isolate->set_context(last_context); |
812 isolate->set_context_exit_happened(true); | 809 isolate->set_context_exit_happened(true); |
813 } | 810 } |
814 | 811 |
815 | 812 |
816 static void* DecodeSmiToAligned(i::Object* value, const char* location) { | 813 void Context::SetData(v8::Handle<Value> data) { |
817 ApiCheck(value->IsSmi(), location, "Not a Smi"); | 814 i::Handle<i::Context> env = Utils::OpenHandle(this); |
818 return reinterpret_cast<void*>(value); | 815 i::Isolate* isolate = env->GetIsolate(); |
| 816 if (IsDeadCheck(isolate, "v8::Context::SetData()")) return; |
| 817 i::Handle<i::Object> raw_data = Utils::OpenHandle(*data); |
| 818 ASSERT(env->IsNativeContext()); |
| 819 if (env->IsNativeContext()) { |
| 820 env->set_data(*raw_data); |
| 821 } |
819 } | 822 } |
820 | 823 |
821 | 824 |
822 static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) { | 825 v8::Local<v8::Value> Context::GetData() { |
823 i::Smi* smi = reinterpret_cast<i::Smi*>(value); | 826 i::Handle<i::Context> env = Utils::OpenHandle(this); |
824 ApiCheck(smi->IsSmi(), location, "Pointer is not aligned"); | 827 i::Isolate* isolate = env->GetIsolate(); |
825 return smi; | 828 if (IsDeadCheck(isolate, "v8::Context::GetData()")) { |
826 } | 829 return Local<Value>(); |
827 | |
828 | |
829 static i::Handle<i::FixedArray> EmbedderDataFor(Context* context, | |
830 int index, | |
831 bool can_grow, | |
832 const char* location) { | |
833 i::Handle<i::Context> env = Utils::OpenHandle(context); | |
834 bool ok = !IsDeadCheck(env->GetIsolate(), location) && | |
835 ApiCheck(env->IsNativeContext(), location, "Not a native context") && | |
836 ApiCheck(index >= 0, location, "Negative index"); | |
837 if (!ok) return i::Handle<i::FixedArray>(); | |
838 i::Handle<i::FixedArray> data(env->embedder_data()); | |
839 if (index < data->length()) return data; | |
840 if (!can_grow) { | |
841 Utils::ReportApiFailure(location, "Index too large"); | |
842 return i::Handle<i::FixedArray>(); | |
843 } | 830 } |
844 int new_size = i::Max(index, data->length() << 1) + 1; | 831 ASSERT(env->IsNativeContext()); |
845 data = env->GetIsolate()->factory()->CopySizeFixedArray(data, new_size); | 832 if (!env->IsNativeContext()) { |
846 env->set_embedder_data(*data); | 833 return Local<Value>(); |
847 return data; | 834 } |
848 } | 835 i::Handle<i::Object> result(env->data(), isolate); |
849 | |
850 | |
851 v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) { | |
852 const char* location = "v8::Context::GetEmbedderData()"; | |
853 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location); | |
854 if (data.is_null()) return Local<Value>(); | |
855 i::Handle<i::Object> result(data->get(index), data->GetIsolate()); | |
856 return Utils::ToLocal(result); | 836 return Utils::ToLocal(result); |
857 } | 837 } |
858 | 838 |
859 | 839 |
860 void Context::SetEmbedderData(int index, v8::Handle<Value> value) { | |
861 const char* location = "v8::Context::SetEmbedderData()"; | |
862 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location); | |
863 if (data.is_null()) return; | |
864 i::Handle<i::Object> val = Utils::OpenHandle(*value); | |
865 data->set(index, *val); | |
866 ASSERT_EQ(*Utils::OpenHandle(*value), | |
867 *Utils::OpenHandle(*GetEmbedderData(index))); | |
868 } | |
869 | |
870 | |
871 void* Context::SlowGetAlignedPointerFromEmbedderData(int index) { | |
872 const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()"; | |
873 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location); | |
874 if (data.is_null()) return NULL; | |
875 return DecodeSmiToAligned(data->get(index), location); | |
876 } | |
877 | |
878 | |
879 void Context::SetAlignedPointerInEmbedderData(int index, void* value) { | |
880 const char* location = "v8::Context::SetAlignedPointerInEmbedderData()"; | |
881 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location); | |
882 data->set(index, EncodeAlignedAsSmi(value, location)); | |
883 ASSERT_EQ(value, GetAlignedPointerFromEmbedderData(index)); | |
884 } | |
885 | |
886 | |
887 i::Object** v8::HandleScope::RawClose(i::Object** value) { | 840 i::Object** v8::HandleScope::RawClose(i::Object** value) { |
888 if (!ApiCheck(!is_closed_, | 841 if (!ApiCheck(!is_closed_, |
889 "v8::HandleScope::Close()", | 842 "v8::HandleScope::Close()", |
890 "Local scope has already been closed")) { | 843 "Local scope has already been closed")) { |
891 return 0; | 844 return 0; |
892 } | 845 } |
893 LOG_API(isolate_, "CloseHandleScope"); | 846 LOG_API(isolate_, "CloseHandleScope"); |
894 | 847 |
895 // Read the result before popping the handle block. | 848 // Read the result before popping the handle block. |
896 i::Object* result = NULL; | 849 i::Object* result = NULL; |
(...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2275 return false; | 2228 return false; |
2276 } | 2229 } |
2277 return Utils::OpenHandle(this)->IsBoolean(); | 2230 return Utils::OpenHandle(this)->IsBoolean(); |
2278 } | 2231 } |
2279 | 2232 |
2280 | 2233 |
2281 bool Value::IsExternal() const { | 2234 bool Value::IsExternal() const { |
2282 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) { | 2235 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsExternal()")) { |
2283 return false; | 2236 return false; |
2284 } | 2237 } |
2285 return Utils::OpenHandle(this)->IsExternal(); | 2238 return Utils::OpenHandle(this)->IsForeign(); |
2286 } | 2239 } |
2287 | 2240 |
2288 | 2241 |
2289 bool Value::IsInt32() const { | 2242 bool Value::IsInt32() const { |
2290 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false; | 2243 if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsInt32()")) return false; |
2291 i::Handle<i::Object> obj = Utils::OpenHandle(this); | 2244 i::Handle<i::Object> obj = Utils::OpenHandle(this); |
2292 if (obj->IsSmi()) return true; | 2245 if (obj->IsSmi()) return true; |
2293 if (obj->IsNumber()) { | 2246 if (obj->IsNumber()) { |
2294 double value = obj->Number(); | 2247 double value = obj->Number(); |
2295 static const i::DoubleRepresentation minus_zero(-0.0); | 2248 static const i::DoubleRepresentation minus_zero(-0.0); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2504 EXCEPTION_PREAMBLE(isolate); | 2457 EXCEPTION_PREAMBLE(isolate); |
2505 num = i::Execution::ToInteger(obj, &has_pending_exception); | 2458 num = i::Execution::ToInteger(obj, &has_pending_exception); |
2506 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>()); | 2459 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>()); |
2507 } | 2460 } |
2508 return Local<Integer>(ToApi<Integer>(num)); | 2461 return Local<Integer>(ToApi<Integer>(num)); |
2509 } | 2462 } |
2510 | 2463 |
2511 | 2464 |
2512 void External::CheckCast(v8::Value* that) { | 2465 void External::CheckCast(v8::Value* that) { |
2513 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return; | 2466 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Cast()")) return; |
2514 ApiCheck(Utils::OpenHandle(that)->IsExternal(), | 2467 i::Handle<i::Object> obj = Utils::OpenHandle(that); |
| 2468 ApiCheck(obj->IsForeign(), |
2515 "v8::External::Cast()", | 2469 "v8::External::Cast()", |
2516 "Could not convert to external"); | 2470 "Could not convert to external"); |
2517 } | 2471 } |
2518 | 2472 |
2519 | 2473 |
2520 void v8::Object::CheckCast(Value* that) { | 2474 void v8::Object::CheckCast(Value* that) { |
2521 if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return; | 2475 if (IsDeadCheck(i::Isolate::Current(), "v8::Object::Cast()")) return; |
2522 i::Handle<i::Object> obj = Utils::OpenHandle(that); | 2476 i::Handle<i::Object> obj = Utils::OpenHandle(that); |
2523 ApiCheck(obj->IsJSObject(), | 2477 ApiCheck(obj->IsJSObject(), |
2524 "v8::Object::Cast()", | 2478 "v8::Object::Cast()", |
(...skipping 1742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4267 | 4221 |
4268 int v8::Object::InternalFieldCount() { | 4222 int v8::Object::InternalFieldCount() { |
4269 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 4223 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
4270 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) { | 4224 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) { |
4271 return 0; | 4225 return 0; |
4272 } | 4226 } |
4273 return obj->GetInternalFieldCount(); | 4227 return obj->GetInternalFieldCount(); |
4274 } | 4228 } |
4275 | 4229 |
4276 | 4230 |
4277 static bool InternalFieldOK(i::Handle<i::JSObject> obj, | 4231 Local<Value> v8::Object::CheckedGetInternalField(int index) { |
4278 int index, | |
4279 const char* location) { | |
4280 return !IsDeadCheck(obj->GetIsolate(), location) && | |
4281 ApiCheck(index < obj->GetInternalFieldCount(), | |
4282 location, | |
4283 "Internal field out of bounds"); | |
4284 } | |
4285 | |
4286 | |
4287 Local<Value> v8::Object::SlowGetInternalField(int index) { | |
4288 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 4232 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
4289 const char* location = "v8::Object::GetInternalField()"; | 4233 if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) { |
4290 if (!InternalFieldOK(obj, index, location)) return Local<Value>(); | 4234 return Local<Value>(); |
4291 i::Handle<i::Object> value(obj->GetInternalField(index), obj->GetIsolate()); | 4235 } |
4292 return Utils::ToLocal(value); | 4236 if (!ApiCheck(index < obj->GetInternalFieldCount(), |
| 4237 "v8::Object::GetInternalField()", |
| 4238 "Reading internal field out of bounds")) { |
| 4239 return Local<Value>(); |
| 4240 } |
| 4241 i::Handle<i::Object> value(obj->GetInternalField(index)); |
| 4242 Local<Value> result = Utils::ToLocal(value); |
| 4243 #ifdef DEBUG |
| 4244 Local<Value> unchecked = UncheckedGetInternalField(index); |
| 4245 ASSERT(unchecked.IsEmpty() || (unchecked == result)); |
| 4246 #endif |
| 4247 return result; |
4293 } | 4248 } |
4294 | 4249 |
4295 | 4250 |
4296 void v8::Object::SetInternalField(int index, v8::Handle<Value> value) { | 4251 void v8::Object::SetInternalField(int index, v8::Handle<Value> value) { |
4297 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 4252 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
4298 const char* location = "v8::Object::SetInternalField()"; | 4253 i::Isolate* isolate = obj->GetIsolate(); |
4299 if (!InternalFieldOK(obj, index, location)) return; | 4254 if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) { |
| 4255 return; |
| 4256 } |
| 4257 if (!ApiCheck(index < obj->GetInternalFieldCount(), |
| 4258 "v8::Object::SetInternalField()", |
| 4259 "Writing internal field out of bounds")) { |
| 4260 return; |
| 4261 } |
| 4262 ENTER_V8(isolate); |
4300 i::Handle<i::Object> val = Utils::OpenHandle(*value); | 4263 i::Handle<i::Object> val = Utils::OpenHandle(*value); |
4301 obj->SetInternalField(index, *val); | 4264 obj->SetInternalField(index, *val); |
4302 ASSERT_EQ(value, GetInternalField(index)); | |
4303 } | 4265 } |
4304 | 4266 |
4305 | 4267 |
4306 void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) { | 4268 static bool CanBeEncodedAsSmi(void* ptr) { |
4307 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 4269 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr); |
4308 const char* location = "v8::Object::GetAlignedPointerFromInternalField()"; | 4270 return ((address & i::kEncodablePointerMask) == 0); |
4309 if (!InternalFieldOK(obj, index, location)) return NULL; | |
4310 return DecodeSmiToAligned(obj->GetInternalField(index), location); | |
4311 } | 4271 } |
4312 | 4272 |
4313 | 4273 |
4314 void v8::Object::SetAlignedPointerInInternalField(int index, void* value) { | 4274 static i::Smi* EncodeAsSmi(void* ptr) { |
4315 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 4275 ASSERT(CanBeEncodedAsSmi(ptr)); |
4316 const char* location = "v8::Object::SetAlignedPointerInInternalField()"; | 4276 const uintptr_t address = reinterpret_cast<uintptr_t>(ptr); |
4317 if (!InternalFieldOK(obj, index, location)) return; | 4277 i::Smi* result = reinterpret_cast<i::Smi*>(address << i::kPointerToSmiShift); |
4318 obj->SetInternalField(index, EncodeAlignedAsSmi(value, location)); | 4278 ASSERT(i::Internals::HasSmiTag(result)); |
4319 ASSERT_EQ(value, GetAlignedPointerFromInternalField(index)); | 4279 ASSERT_EQ(result, i::Smi::FromInt(result->value())); |
| 4280 ASSERT_EQ(ptr, i::Internals::GetExternalPointerFromSmi(result)); |
| 4281 return result; |
4320 } | 4282 } |
4321 | 4283 |
4322 | 4284 |
4323 static void* ExternalValue(i::Object* obj) { | 4285 void v8::Object::SetPointerInInternalField(int index, void* value) { |
4324 // Obscure semantics for undefined, but somehow checked in our unit tests... | 4286 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); |
4325 if (obj->IsUndefined()) return NULL; | 4287 ENTER_V8(isolate); |
4326 i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0); | 4288 if (CanBeEncodedAsSmi(value)) { |
4327 return i::Foreign::cast(foreign)->foreign_address(); | 4289 Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value)); |
| 4290 } else { |
| 4291 HandleScope scope; |
| 4292 i::Handle<i::Foreign> foreign = |
| 4293 isolate->factory()->NewForeign( |
| 4294 reinterpret_cast<i::Address>(value), i::TENURED); |
| 4295 if (!foreign.is_null()) { |
| 4296 Utils::OpenHandle(this)->SetInternalField(index, *foreign); |
| 4297 } |
| 4298 } |
| 4299 ASSERT_EQ(value, GetPointerFromInternalField(index)); |
4328 } | 4300 } |
4329 | 4301 |
4330 | 4302 |
4331 void* Object::GetPointerFromInternalField(int index) { | |
4332 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | |
4333 const char* location = "v8::Object::GetPointerFromInternalField()"; | |
4334 if (!InternalFieldOK(obj, index, location)) return NULL; | |
4335 return ExternalValue(obj->GetInternalField(index)); | |
4336 } | |
4337 | |
4338 | |
4339 // --- E n v i r o n m e n t --- | 4303 // --- E n v i r o n m e n t --- |
4340 | 4304 |
4341 | 4305 |
4342 bool v8::V8::Initialize() { | 4306 bool v8::V8::Initialize() { |
4343 i::Isolate* isolate = i::Isolate::UncheckedCurrent(); | 4307 i::Isolate* isolate = i::Isolate::UncheckedCurrent(); |
4344 if (isolate != NULL && isolate->IsInitialized()) { | 4308 if (isolate != NULL && isolate->IsInitialized()) { |
4345 return true; | 4309 return true; |
4346 } | 4310 } |
4347 return InitializeHelper(); | 4311 return InitializeHelper(); |
4348 } | 4312 } |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4764 | 4728 |
4765 | 4729 |
4766 bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) { | 4730 bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) { |
4767 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()", | 4731 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()", |
4768 return false); | 4732 return false); |
4769 i::Object* obj = *Utils::OpenHandle(*value); | 4733 i::Object* obj = *Utils::OpenHandle(*value); |
4770 return obj->IsInstanceOf(*Utils::OpenHandle(this)); | 4734 return obj->IsInstanceOf(*Utils::OpenHandle(this)); |
4771 } | 4735 } |
4772 | 4736 |
4773 | 4737 |
4774 Local<External> v8::External::New(void* value) { | 4738 static Local<External> ExternalNewImpl(void* data) { |
4775 STATIC_ASSERT(sizeof(value) == sizeof(i::Address)); | 4739 return Utils::ToLocal(FACTORY->NewForeign(static_cast<i::Address>(data))); |
| 4740 } |
| 4741 |
| 4742 static void* ExternalValueImpl(i::Handle<i::Object> obj) { |
| 4743 return reinterpret_cast<void*>(i::Foreign::cast(*obj)->foreign_address()); |
| 4744 } |
| 4745 |
| 4746 |
| 4747 Local<Value> v8::External::Wrap(void* data) { |
| 4748 i::Isolate* isolate = i::Isolate::Current(); |
| 4749 STATIC_ASSERT(sizeof(data) == sizeof(i::Address)); |
| 4750 EnsureInitializedForIsolate(isolate, "v8::External::Wrap()"); |
| 4751 LOG_API(isolate, "External::Wrap"); |
| 4752 ENTER_V8(isolate); |
| 4753 |
| 4754 v8::Local<v8::Value> result = CanBeEncodedAsSmi(data) |
| 4755 ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data))) |
| 4756 : v8::Local<v8::Value>(ExternalNewImpl(data)); |
| 4757 |
| 4758 ASSERT_EQ(data, Unwrap(result)); |
| 4759 return result; |
| 4760 } |
| 4761 |
| 4762 |
| 4763 void* v8::Object::SlowGetPointerFromInternalField(int index) { |
| 4764 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); |
| 4765 i::Object* value = obj->GetInternalField(index); |
| 4766 if (value->IsSmi()) { |
| 4767 return i::Internals::GetExternalPointerFromSmi(value); |
| 4768 } else if (value->IsForeign()) { |
| 4769 return reinterpret_cast<void*>(i::Foreign::cast(value)->foreign_address()); |
| 4770 } else { |
| 4771 return NULL; |
| 4772 } |
| 4773 } |
| 4774 |
| 4775 |
| 4776 void* v8::External::FullUnwrap(v8::Handle<v8::Value> wrapper) { |
| 4777 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Unwrap()")) return 0; |
| 4778 i::Handle<i::Object> obj = Utils::OpenHandle(*wrapper); |
| 4779 void* result; |
| 4780 if (obj->IsSmi()) { |
| 4781 result = i::Internals::GetExternalPointerFromSmi(*obj); |
| 4782 } else if (obj->IsForeign()) { |
| 4783 result = ExternalValueImpl(obj); |
| 4784 } else { |
| 4785 result = NULL; |
| 4786 } |
| 4787 ASSERT_EQ(result, QuickUnwrap(wrapper)); |
| 4788 return result; |
| 4789 } |
| 4790 |
| 4791 |
| 4792 Local<External> v8::External::New(void* data) { |
| 4793 STATIC_ASSERT(sizeof(data) == sizeof(i::Address)); |
4776 i::Isolate* isolate = i::Isolate::Current(); | 4794 i::Isolate* isolate = i::Isolate::Current(); |
4777 EnsureInitializedForIsolate(isolate, "v8::External::New()"); | 4795 EnsureInitializedForIsolate(isolate, "v8::External::New()"); |
4778 LOG_API(isolate, "External::New"); | 4796 LOG_API(isolate, "External::New"); |
4779 ENTER_V8(isolate); | 4797 ENTER_V8(isolate); |
4780 i::Handle<i::JSObject> external = isolate->factory()->NewExternal(value); | 4798 return ExternalNewImpl(data); |
4781 return Utils::ExternalToLocal(external); | |
4782 } | 4799 } |
4783 | 4800 |
4784 | 4801 |
4785 void* External::Value() const { | 4802 void* External::Value() const { |
4786 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return NULL; | 4803 if (IsDeadCheck(i::Isolate::Current(), "v8::External::Value()")) return 0; |
4787 return ExternalValue(*Utils::OpenHandle(this)); | 4804 i::Handle<i::Object> obj = Utils::OpenHandle(this); |
| 4805 return ExternalValueImpl(obj); |
4788 } | 4806 } |
4789 | 4807 |
4790 | 4808 |
4791 Local<String> v8::String::Empty() { | 4809 Local<String> v8::String::Empty() { |
4792 i::Isolate* isolate = i::Isolate::Current(); | 4810 i::Isolate* isolate = i::Isolate::Current(); |
4793 if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) { | 4811 if (!EnsureInitializedForIsolate(isolate, "v8::String::Empty()")) { |
4794 return v8::Local<String>(); | 4812 return v8::Local<String>(); |
4795 } | 4813 } |
4796 LOG_API(isolate, "String::Empty()"); | 4814 LOG_API(isolate, "String::Empty()"); |
4797 return Utils::ToLocal(isolate->factory()->empty_symbol()); | 4815 return Utils::ToLocal(isolate->factory()->empty_symbol()); |
(...skipping 1861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6659 | 6677 |
6660 v->VisitPointers(blocks_.first(), first_block_limit_); | 6678 v->VisitPointers(blocks_.first(), first_block_limit_); |
6661 | 6679 |
6662 for (int i = 1; i < blocks_.length(); i++) { | 6680 for (int i = 1; i < blocks_.length(); i++) { |
6663 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]); | 6681 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]); |
6664 } | 6682 } |
6665 } | 6683 } |
6666 | 6684 |
6667 | 6685 |
6668 } } // namespace v8::internal | 6686 } } // namespace v8::internal |
OLD | NEW |