blob: 2ed3ad27e5b405708f5d3be79f393aa3f7a402e1 [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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007#include "src/api.h"
8#include "src/handles.h"
9#include "src/isolate.h"
10
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080011namespace v8 {
12namespace internal {
13
14template <typename Char, typename Base>
15class SimpleStringResource : public Base {
16 public:
17 // Takes ownership of |data|.
18 SimpleStringResource(Char* data, size_t length)
19 : data_(data),
20 length_(length) {}
21
22 virtual ~SimpleStringResource() { delete[] data_; }
23
24 virtual const Char* data() const { return data_; }
25
26 virtual size_t length() const { return length_; }
27
28 private:
29 Char* const data_;
30 const size_t length_;
31};
32
33
Ben Murdochb8a8cc12014-11-26 15:28:44 +000034typedef SimpleStringResource<char, v8::String::ExternalOneByteStringResource>
35 SimpleOneByteStringResource;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080036typedef SimpleStringResource<uc16, v8::String::ExternalStringResource>
37 SimpleTwoByteStringResource;
38
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080039const char* const ExternalizeStringExtension::kSource =
40 "native function externalizeString();"
Ben Murdoch097c5b22016-05-18 11:27:45 +010041 "native function isOneByteString();"
42 "function x() { return 1; }";
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080043
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044v8::Local<v8::FunctionTemplate>
Ben Murdochb8a8cc12014-11-26 15:28:44 +000045ExternalizeStringExtension::GetNativeFunctionTemplate(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000046 v8::Isolate* isolate, v8::Local<v8::String> str) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047 if (strcmp(*v8::String::Utf8Value(str), "externalizeString") == 0) {
48 return v8::FunctionTemplate::New(isolate,
49 ExternalizeStringExtension::Externalize);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080050 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000051 DCHECK(strcmp(*v8::String::Utf8Value(str), "isOneByteString") == 0);
52 return v8::FunctionTemplate::New(isolate,
53 ExternalizeStringExtension::IsOneByte);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080054 }
55}
56
57
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058void ExternalizeStringExtension::Externalize(
59 const v8::FunctionCallbackInfo<v8::Value>& args) {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080060 if (args.Length() < 1 || !args[0]->IsString()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000061 args.GetIsolate()->ThrowException(
62 v8::String::NewFromUtf8(
63 args.GetIsolate(),
64 "First parameter to externalizeString() must be a string.",
65 NewStringType::kNormal).ToLocalChecked());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000066 return;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080067 }
68 bool force_two_byte = false;
69 if (args.Length() >= 2) {
70 if (args[1]->IsBoolean()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000071 force_two_byte =
72 args[1]
73 ->BooleanValue(args.GetIsolate()->GetCurrentContext())
74 .FromJust();
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080075 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000076 args.GetIsolate()->ThrowException(
77 v8::String::NewFromUtf8(
78 args.GetIsolate(),
79 "Second parameter to externalizeString() must be a boolean.",
80 NewStringType::kNormal).ToLocalChecked());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081 return;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080082 }
83 }
84 bool result = false;
85 Handle<String> string = Utils::OpenHandle(*args[0].As<v8::String>());
86 if (string->IsExternalString()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000087 args.GetIsolate()->ThrowException(
88 v8::String::NewFromUtf8(args.GetIsolate(),
89 "externalizeString() can't externalize twice.",
90 NewStringType::kNormal).ToLocalChecked());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000091 return;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080092 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000093 if (string->IsOneByteRepresentation() && !force_two_byte) {
94 uint8_t* data = new uint8_t[string->length()];
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080095 String::WriteToFlat(*string, data, 0, string->length());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000096 SimpleOneByteStringResource* resource = new SimpleOneByteStringResource(
97 reinterpret_cast<char*>(data), string->length());
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080098 result = string->MakeExternal(resource);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000099 if (result) {
100 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101 isolate->heap()->RegisterExternalString(*string);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800102 }
103 if (!result) delete resource;
104 } else {
105 uc16* data = new uc16[string->length()];
106 String::WriteToFlat(*string, data, 0, string->length());
107 SimpleTwoByteStringResource* resource = new SimpleTwoByteStringResource(
108 data, string->length());
109 result = string->MakeExternal(resource);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000110 if (result) {
111 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000112 isolate->heap()->RegisterExternalString(*string);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800113 }
114 if (!result) delete resource;
115 }
116 if (!result) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000117 args.GetIsolate()->ThrowException(
118 v8::String::NewFromUtf8(args.GetIsolate(),
119 "externalizeString() failed.",
120 NewStringType::kNormal).ToLocalChecked());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000121 return;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800122 }
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800123}
124
125
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000126void ExternalizeStringExtension::IsOneByte(
127 const v8::FunctionCallbackInfo<v8::Value>& args) {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800128 if (args.Length() != 1 || !args[0]->IsString()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000129 args.GetIsolate()->ThrowException(
130 v8::String::NewFromUtf8(
131 args.GetIsolate(),
132 "isOneByteString() requires a single string argument.",
133 NewStringType::kNormal).ToLocalChecked());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000134 return;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800135 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136 bool is_one_byte =
137 Utils::OpenHandle(*args[0].As<v8::String>())->IsOneByteRepresentation();
138 args.GetReturnValue().Set(is_one_byte);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800139}
140
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000141} // namespace internal
142} // namespace v8