blob: 8d38dfa0f015eee3e049412c9fc73a79b18c30d4 [file] [log] [blame]
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08001// Copyright 2010 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08004
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#include "src/extensions/externalize-string-extension.h"
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08006
7namespace v8 {
8namespace internal {
9
10template <typename Char, typename Base>
11class SimpleStringResource : public Base {
12 public:
13 // Takes ownership of |data|.
14 SimpleStringResource(Char* data, size_t length)
15 : data_(data),
16 length_(length) {}
17
18 virtual ~SimpleStringResource() { delete[] data_; }
19
20 virtual const Char* data() const { return data_; }
21
22 virtual size_t length() const { return length_; }
23
24 private:
25 Char* const data_;
26 const size_t length_;
27};
28
29
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030typedef SimpleStringResource<char, v8::String::ExternalOneByteStringResource>
31 SimpleOneByteStringResource;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080032typedef SimpleStringResource<uc16, v8::String::ExternalStringResource>
33 SimpleTwoByteStringResource;
34
35
36const char* const ExternalizeStringExtension::kSource =
37 "native function externalizeString();"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000038 "native function isOneByteString();";
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080039
Ben Murdochb8a8cc12014-11-26 15:28:44 +000040v8::Handle<v8::FunctionTemplate>
41ExternalizeStringExtension::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);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080046 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047 DCHECK(strcmp(*v8::String::Utf8Value(str), "isOneByteString") == 0);
48 return v8::FunctionTemplate::New(isolate,
49 ExternalizeStringExtension::IsOneByte);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080050 }
51}
52
53
Ben Murdochb8a8cc12014-11-26 15:28:44 +000054void ExternalizeStringExtension::Externalize(
55 const v8::FunctionCallbackInfo<v8::Value>& args) {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080056 if (args.Length() < 1 || !args[0]->IsString()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000057 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
58 args.GetIsolate(),
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080059 "First parameter to externalizeString() must be a string."));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000060 return;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080061 }
62 bool force_two_byte = false;
63 if (args.Length() >= 2) {
64 if (args[1]->IsBoolean()) {
65 force_two_byte = args[1]->BooleanValue();
66 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000067 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
68 args.GetIsolate(),
69 "Second parameter to externalizeString() must be a boolean."));
70 return;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080071 }
72 }
73 bool result = false;
74 Handle<String> string = Utils::OpenHandle(*args[0].As<v8::String>());
75 if (string->IsExternalString()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000076 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
77 args.GetIsolate(),
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080078 "externalizeString() can't externalize twice."));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000079 return;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080080 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081 if (string->IsOneByteRepresentation() && !force_two_byte) {
82 uint8_t* data = new uint8_t[string->length()];
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080083 String::WriteToFlat(*string, data, 0, string->length());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000084 SimpleOneByteStringResource* resource = new SimpleOneByteStringResource(
85 reinterpret_cast<char*>(data), string->length());
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080086 result = string->MakeExternal(resource);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000087 if (result) {
88 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
89 isolate->heap()->external_string_table()->AddString(*string);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080090 }
91 if (!result) delete resource;
92 } else {
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);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000098 if (result) {
99 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
100 isolate->heap()->external_string_table()->AddString(*string);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800101 }
102 if (!result) delete resource;
103 }
104 if (!result) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
106 args.GetIsolate(), "externalizeString() failed."));
107 return;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800108 }
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800109}
110
111
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000112void ExternalizeStringExtension::IsOneByte(
113 const v8::FunctionCallbackInfo<v8::Value>& args) {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800114 if (args.Length() != 1 || !args[0]->IsString()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000115 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8(
116 args.GetIsolate(),
117 "isOneByteString() requires a single string argument."));
118 return;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800119 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000120 bool is_one_byte =
121 Utils::OpenHandle(*args[0].As<v8::String>())->IsOneByteRepresentation();
122 args.GetReturnValue().Set(is_one_byte);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800123}
124
125} } // namespace v8::internal