blob: adc5577d9e5adf30491b078271c1b7e6afe69697 [file] [log] [blame]
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +00001// Copyright 2010 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
27
28#include "externalize-string-extension.h"
29
30namespace v8 {
31namespace internal {
32
33template <typename Char, typename Base>
34class SimpleStringResource : public Base {
35 public:
36 // Takes ownership of |data|.
37 SimpleStringResource(Char* data, size_t length)
38 : data_(data),
39 length_(length) {}
40
41 virtual ~SimpleStringResource() { delete[] data_; }
42
43 virtual const Char* data() const { return data_; }
44
45 virtual size_t length() const { return length_; }
46
47 private:
48 Char* const data_;
49 const size_t length_;
50};
51
52
53typedef SimpleStringResource<char, v8::String::ExternalAsciiStringResource>
54 SimpleAsciiStringResource;
55typedef SimpleStringResource<uc16, v8::String::ExternalStringResource>
56 SimpleTwoByteStringResource;
57
58
59const char* const ExternalizeStringExtension::kSource =
60 "native function externalizeString();"
61 "native function isAsciiString();";
62
machenbach@chromium.org9f18d912013-11-28 13:42:41 +000063v8::Handle<v8::FunctionTemplate>
64ExternalizeStringExtension::GetNativeFunctionTemplate(
65 v8::Isolate* isolate, v8::Handle<v8::String> str) {
ulan@chromium.org906e2fb2013-05-14 08:14:38 +000066 if (strcmp(*v8::String::Utf8Value(str), "externalizeString") == 0) {
hpayer@chromium.org4f99be92013-12-18 16:23:55 +000067 return v8::FunctionTemplate::New(isolate,
68 ExternalizeStringExtension::Externalize);
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +000069 } else {
ulan@chromium.org906e2fb2013-05-14 08:14:38 +000070 ASSERT(strcmp(*v8::String::Utf8Value(str), "isAsciiString") == 0);
hpayer@chromium.org4f99be92013-12-18 16:23:55 +000071 return v8::FunctionTemplate::New(isolate,
72 ExternalizeStringExtension::IsAscii);
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +000073 }
74}
75
76
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +000077void ExternalizeStringExtension::Externalize(
78 const v8::FunctionCallbackInfo<v8::Value>& args) {
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +000079 if (args.Length() < 1 || !args[0]->IsString()) {
machenbach@chromium.orgf9841892013-11-25 12:01:13 +000080 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
81 args.GetIsolate(),
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +000082 "First parameter to externalizeString() must be a string."));
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +000083 return;
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +000084 }
85 bool force_two_byte = false;
86 if (args.Length() >= 2) {
87 if (args[1]->IsBoolean()) {
88 force_two_byte = args[1]->BooleanValue();
89 } else {
machenbach@chromium.orgf9841892013-11-25 12:01:13 +000090 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
91 args.GetIsolate(),
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +000092 "Second parameter to externalizeString() must be a boolean."));
93 return;
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +000094 }
95 }
96 bool result = false;
97 Handle<String> string = Utils::OpenHandle(*args[0].As<v8::String>());
98 if (string->IsExternalString()) {
machenbach@chromium.orgf9841892013-11-25 12:01:13 +000099 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
100 args.GetIsolate(),
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000101 "externalizeString() can't externalize twice."));
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +0000102 return;
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000103 }
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000104 if (string->IsOneByteRepresentation() && !force_two_byte) {
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000105 uint8_t* data = new uint8_t[string->length()];
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000106 String::WriteToFlat(*string, data, 0, string->length());
107 SimpleAsciiStringResource* resource = new SimpleAsciiStringResource(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000108 reinterpret_cast<char*>(data), string->length());
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000109 result = string->MakeExternal(resource);
machenbach@chromium.orgbcc36722014-03-11 07:52:26 +0000110 if (result) {
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000111 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
112 isolate->heap()->external_string_table()->AddString(*string);
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000113 }
114 if (!result) delete resource;
115 } else {
116 uc16* data = new uc16[string->length()];
117 String::WriteToFlat(*string, data, 0, string->length());
118 SimpleTwoByteStringResource* resource = new SimpleTwoByteStringResource(
119 data, string->length());
120 result = string->MakeExternal(resource);
machenbach@chromium.orgbcc36722014-03-11 07:52:26 +0000121 if (result) {
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000122 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
123 isolate->heap()->external_string_table()->AddString(*string);
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000124 }
125 if (!result) delete resource;
126 }
127 if (!result) {
machenbach@chromium.orgf9841892013-11-25 12:01:13 +0000128 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
129 args.GetIsolate(), "externalizeString() failed."));
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +0000130 return;
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000131 }
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000132}
133
134
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +0000135void ExternalizeStringExtension::IsAscii(
136 const v8::FunctionCallbackInfo<v8::Value>& args) {
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000137 if (args.Length() != 1 || !args[0]->IsString()) {
machenbach@chromium.orgf9841892013-11-25 12:01:13 +0000138 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
139 args.GetIsolate(),
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000140 "isAsciiString() requires a single string argument."));
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +0000141 return;
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000142 }
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +0000143 bool is_one_byte =
144 Utils::OpenHandle(*args[0].As<v8::String>())->IsOneByteRepresentation();
145 args.GetReturnValue().Set(is_one_byte);
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000146}
147
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000148} } // namespace v8::internal