1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "externalize-string-extension.h"
10 template <typename Char, typename Base>
11 class SimpleStringResource : public Base {
13 // Takes ownership of |data|.
14 SimpleStringResource(Char* data, size_t length)
18 virtual ~SimpleStringResource() { delete[] data_; }
20 virtual const Char* data() const { return data_; }
22 virtual size_t length() const { return length_; }
30 typedef SimpleStringResource<char, v8::String::ExternalAsciiStringResource>
31 SimpleAsciiStringResource;
32 typedef SimpleStringResource<uc16, v8::String::ExternalStringResource>
33 SimpleTwoByteStringResource;
36 const char* const ExternalizeStringExtension::kSource =
37 "native function externalizeString();"
38 "native function isAsciiString();";
40 v8::Handle<v8::FunctionTemplate>
41 ExternalizeStringExtension::GetNativeFunctionTemplate(
42 v8::Isolate* isolate, v8::Handle<v8::String> str) {
43 if (strcmp(*v8::String::Utf8Value(str), "externalizeString") == 0) {
44 return v8::FunctionTemplate::New(isolate,
45 ExternalizeStringExtension::Externalize);
47 ASSERT(strcmp(*v8::String::Utf8Value(str), "isAsciiString") == 0);
48 return v8::FunctionTemplate::New(isolate,
49 ExternalizeStringExtension::IsAscii);
54 void ExternalizeStringExtension::Externalize(
55 const v8::FunctionCallbackInfo<v8::Value>& args) {
56 if (args.Length() < 1 || !args[0]->IsString()) {
57 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
59 "First parameter to externalizeString() must be a string."));
62 bool force_two_byte = false;
63 if (args.Length() >= 2) {
64 if (args[1]->IsBoolean()) {
65 force_two_byte = args[1]->BooleanValue();
67 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
69 "Second parameter to externalizeString() must be a boolean."));
74 Handle<String> string = Utils::OpenHandle(*args[0].As<v8::String>());
75 if (string->IsExternalString()) {
76 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
78 "externalizeString() can't externalize twice."));
81 if (string->IsOneByteRepresentation() && !force_two_byte) {
82 uint8_t* data = new uint8_t[string->length()];
83 String::WriteToFlat(*string, data, 0, string->length());
84 SimpleAsciiStringResource* resource = new SimpleAsciiStringResource(
85 reinterpret_cast<char*>(data), string->length());
86 result = string->MakeExternal(resource);
88 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
89 isolate->heap()->external_string_table()->AddString(*string);
91 if (!result) delete resource;
93 uc16* data = new uc16[string->length()];
94 String::WriteToFlat(*string, data, 0, string->length());
95 SimpleTwoByteStringResource* resource = new SimpleTwoByteStringResource(
96 data, string->length());
97 result = string->MakeExternal(resource);
99 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
100 isolate->heap()->external_string_table()->AddString(*string);
102 if (!result) delete resource;
105 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
106 args.GetIsolate(), "externalizeString() failed."));
112 void ExternalizeStringExtension::IsAscii(
113 const v8::FunctionCallbackInfo<v8::Value>& args) {
114 if (args.Length() != 1 || !args[0]->IsString()) {
115 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
117 "isAsciiString() requires a single string argument."));
121 Utils::OpenHandle(*args[0].As<v8::String>())->IsOneByteRepresentation();
122 args.GetReturnValue().Set(is_one_byte);
125 } } // namespace v8::internal