v8

2013-02-22 14 views
8

में मान हैंडल के लिए कास्ट बनाम ToXXX मैं एक C++ प्रोग्राम में सहायक भाषा के रूप में V8 एम्बेड कर रहा हूं।v8

मैं वी 8 से एक Handle<Value> पुनः प्राप्त जब मैं value_handle->IsString() साथ मैं तो पता लगा सकते हैं यह है कि (माना) की तरह

Handle<Value> value_handle = context->Global()->Get(key_handle); 

कुछ फोन एक स्ट्रिंग। और यदि ऐसा है तो मैं इसे अपनी स्ट्रिंग-विशिष्ट विधियों तक पहुंचने के लिए Handle<String> में परिवर्तित कर सकता हूं।

लेकिन वहाँ है कि करने के दो तरीके हो रहा है, या तो:

Handle<String> string = value_handle->ToString(); 

या

Handle<String> string = Handle<String>::Cast(value_handle); 

हालांकि, अरै, और फ़ंक्शन के लिए, कोई toArray() या toFunction तरीकों, बस कास्टिंग ।

तो मेरा प्रश्न है: ए) ToXXX कास्टिंग के लिए सिंटैक्टिक चीनी है? और, यदि नहीं बी) ToXXX विधि क्या कर रही है?

उत्तर

8

ToXXX फ़ंक्शन ईसीएमए -262 5 वीं के section 9 के उपखंडों में वर्णित प्रकार के अभ्यास निष्पादन करते हैं। उदाहरण के लिए ToStringsection 9.8 में वर्णित है: जब गैर-स्ट्रिंग मान दिया जाता है तो यह ऑब्जेक्ट पास करने पर उचित स्ट्रिंग प्रस्तुति वापस कर देगा, यदि आप toString पर कॉल करेंगे (toString मौजूद नहीं है)। ToString के लिए प्रासंगिक कोड: कि दूसरी ओर Handle<XXX>::Cast(...) पर runtime.jsToString

में कॉल api.ccValue::ToString में कोई coercions करता है। यह हैंडल के लिए सिर्फ एक प्रकार का कलाकार है। अनिवार्य रूप से यह केवल static_cast<XXX*> है। डीबग मोड में Handle<T>::Cast(...) चेक किया गया है और प्रकार मेल नहीं होने पर निष्पादन बंद कर दिया जाता है। यदि आपको Handle<Value> दिया गया है तो Object युक्त एक घातक त्रुटि होगी और आप इसे Handle<String> पर डालने की कोशिश कर रहे हैं। जब आप कास्ट के परिणाम का उपयोग करने का प्रयास करते हैं तो रिलीज मोड में एक असंगत प्रकार को कास्टिंग करने के बाद बाद में अजीब परिणाम और संभावित रूप से क्रैश हो जाएंगे। v8.hHandle<T>::Cast में प्रासंगिक कोड (उदाहरण के लिए) String::Cast जो String::CheckCast के माध्यम से कास्ट (यदि चेक सक्षम हैं) को चेक करता है।

+0

हम्म। क्या आप वाकई हुड के नीचे वास्तव में क्या होता है? मेरे पास कुछ अजीब व्यवहार है जहां * कभी-कभी * 'हैंडल ' पर 'टूल्स टूस्ट्रिंग() को कॉल करना एक SEGFAULT में परिणाम होता है यदि 'Value' स्ट्रिंग नहीं है। अन्य बार, यह वही करेगा जो आप वर्णन करते हैं। – namuol

+0

@namuol हाँ मुझे यकीन है। SEGFAULT आपके कोड में एक बग से V8 कोड में एक बग से लेकर कई कारणों से हो सकता है। सवाल करना मुश्किल है कि प्रश्न में कोड को देखे बिना। –

+0

यह पता चला है कि 'ToString' को वास्तव में एक संदर्भ के भीतर काम करने की आवश्यकता है - मैं इसे लगातार संभाल पर एक संदर्भ स्थापित किए बिना बुला रहा था। मैंने अलग-अलग स्टोर को हल करके हल किया था, जिसे हैंडल को मूल्य के साथ बनाया गया था और 'ToString' को कॉल करने से पहले पृथक से एक संदर्भ बनाया था। – namuol

0

हम

V8EXPORT स्थानीय toString() स्थिरांक का पता लगाने कर सकते हैं;

v8.h जहां V8EXPORT कार्यों के लिए एक ओएस निर्भर दृष्टिकोण है की लाइन 971 में

। स्ट्रिंग के हैंडल के


ToString api.cc की लाइन 2362 पर स्थित है

Local<String> Value::ToString() const { 
    i::Handle<i::Object> obj = Utils::OpenHandle(this); 
    i::Handle<i::Object> str; 
    if (obj->IsString()) { 
    str = obj; 
    } else { 
    i::Isolate* isolate = i::Isolate::Current(); 
    if (IsDeadCheck(isolate, "v8::Value::ToString()")) { 
     return Local<String>(); 
    } 
    LOG_API(isolate, "ToString"); 
    ENTER_V8(isolate); 
    EXCEPTION_PREAMBLE(isolate); 
    str = i::Execution::ToString(obj, &has_pending_exception); 
    EXCEPTION_BAILOUT_CHECK(isolate, Local<String>()); 
    } 
    return Local<String>(ToApi<String>(str)); 
} 

स्थिरता के लिए और वी 8 संस्करणों के आगे उन्नयन से लाभ लेते हैं, मैं दृढ़ता से toString (उपयोग करने के लिए सलाह देते हैं) आदिम कलाकारों के बजाय।

+0

नहीं, यह गलत ToString है। जिस पर आप इंगित कर रहे हैं वह ReplacementStringBuilder :: ToString है। आपको इसके बजाय 'api.cc' देखना चाहिए। –

+0

वास्तव में! माफ़ कीजिये। धन्यवाद @ VyacheslavEgorov। खोज करते समय मैंने एक बड़ी गलती की। –

+0

धन्यवाद एबी। आपको लगता है कि ToString कास्टिंग से अधिक भविष्य का प्रमाण क्यों होना चाहिए? अगर मैंने सत्यापित किया है कि हैंडल-> IsString(), तो मेरा वृत्ति एक कास्ट पसंद करना है। – Ian

संबंधित मुद्दे