blob: 831ca74a62f95820c6cacdca9be01a7cea5eb591 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "v8_binding.h"
#include "AtomicString.h"
#include "CString.h"
#include "MathExtras.h"
#include "PlatformString.h"
#include "StringBuffer.h"
#include <v8.h>
namespace WebCore {
// WebCoreStringResource is a helper class for v8ExternalString. It is used
// to manage the life-cycle of the underlying buffer of the external string.
class WebCoreStringResource: public v8::String::ExternalStringResource {
public:
explicit WebCoreStringResource(const String& str)
: impl_(str.impl()) { }
virtual ~WebCoreStringResource() {}
const uint16_t* data() const {
return reinterpret_cast<const uint16_t*>(impl_.characters());
}
size_t length() const { return impl_.length(); }
String webcore_string() { return impl_; }
private:
// A shallow copy of the string.
// Keeps the string buffer alive until the V8 engine garbage collects it.
String impl_;
};
String v8StringToWebCoreString(
v8::Handle<v8::String> v8_str, bool externalize) {
WebCoreStringResource* str_resource = static_cast<WebCoreStringResource*>(
v8_str->GetExternalStringResource());
if (str_resource) {
return str_resource->webcore_string();
}
int length = v8_str->Length();
if (length == 0) {
// Avoid trying to morph empty strings, as they do not have enough room to
// contain the external reference.
return StringImpl::empty();
}
UChar* buffer;
String result = String::createUninitialized(length, buffer);
v8_str->Write(reinterpret_cast<uint16_t*>(buffer), 0, length);
if (externalize) {
WebCoreStringResource* resource = new WebCoreStringResource(result);
if (!v8_str->MakeExternal(resource)) {
// In case of a failure delete the external resource as it was not used.
delete resource;
}
}
return result;
}
String v8ValueToWebCoreString(v8::Handle<v8::Value> obj) {
if (obj->IsString()) {
v8::Handle<v8::String> v8_str = v8::Handle<v8::String>::Cast(obj);
String webCoreString = v8StringToWebCoreString(v8_str, true);
return webCoreString;
} else if (obj->IsInt32()) {
int value = obj->Int32Value();
// Most numbers used are <= 100. Even if they aren't used
// there's very little in using the space.
const int kLowNumbers = 100;
static AtomicString lowNumbers[kLowNumbers + 1];
String webCoreString;
if (0 <= value && value <= kLowNumbers) {
webCoreString = lowNumbers[value];
if (!webCoreString) {
AtomicString valueString = AtomicString(String::number(value));
lowNumbers[value] = valueString;
webCoreString = valueString;
}
} else {
webCoreString = String::number(value);
}
return webCoreString;
} else {
v8::TryCatch block;
v8::Handle<v8::String> v8_str = obj->ToString();
return v8StringToWebCoreString(v8_str, false);
}
}
AtomicString v8StringToAtomicWebCoreString(v8::Handle<v8::String> v8_str) {
String str = v8StringToWebCoreString(v8_str, true);
return AtomicString(str);
}
AtomicString v8ValueToAtomicWebCoreString(v8::Handle<v8::Value> v8_str) {
String str = v8ValueToWebCoreString(v8_str);
return AtomicString(str);
}
v8::Handle<v8::String> v8String(const String& str) {
if (!str.length())
return v8::String::Empty();
return v8::String::NewExternal(new WebCoreStringResource(str));
}
v8::Local<v8::String> v8ExternalString(const String& str) {
if (!str.length())
return v8::String::Empty();
return v8::String::NewExternal(new WebCoreStringResource(str));
}
} // namespace WebCore
|