Home | History | Annotate | Download | only in extensions
      1 // 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 
     30 namespace v8 {
     31 namespace internal {
     32 
     33 template <typename Char, typename Base>
     34 class 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 
     53 typedef SimpleStringResource<char, v8::String::ExternalAsciiStringResource>
     54     SimpleAsciiStringResource;
     55 typedef SimpleStringResource<uc16, v8::String::ExternalStringResource>
     56     SimpleTwoByteStringResource;
     57 
     58 
     59 const char* const ExternalizeStringExtension::kSource =
     60     "native function externalizeString();"
     61     "native function isAsciiString();";
     62 
     63 
     64 v8::Handle<v8::FunctionTemplate> ExternalizeStringExtension::GetNativeFunction(
     65     v8::Handle<v8::String> str) {
     66   if (strcmp(*v8::String::Utf8Value(str), "externalizeString") == 0) {
     67     return v8::FunctionTemplate::New(ExternalizeStringExtension::Externalize);
     68   } else {
     69     ASSERT(strcmp(*v8::String::Utf8Value(str), "isAsciiString") == 0);
     70     return v8::FunctionTemplate::New(ExternalizeStringExtension::IsAscii);
     71   }
     72 }
     73 
     74 
     75 void ExternalizeStringExtension::Externalize(
     76     const v8::FunctionCallbackInfo<v8::Value>& args) {
     77   if (args.Length() < 1 || !args[0]->IsString()) {
     78     v8::ThrowException(v8::String::New(
     79         "First parameter to externalizeString() must be a string."));
     80     return;
     81   }
     82   bool force_two_byte = false;
     83   if (args.Length() >= 2) {
     84     if (args[1]->IsBoolean()) {
     85       force_two_byte = args[1]->BooleanValue();
     86     } else {
     87       v8::ThrowException(v8::String::New(
     88         "Second parameter to externalizeString() must be a boolean."));
     89       return;
     90     }
     91   }
     92   bool result = false;
     93   Handle<String> string = Utils::OpenHandle(*args[0].As<v8::String>());
     94   if (string->IsExternalString()) {
     95     v8::ThrowException(v8::String::New(
     96         "externalizeString() can't externalize twice."));
     97     return;
     98   }
     99   if (string->IsOneByteRepresentation() && !force_two_byte) {
    100     uint8_t* data = new uint8_t[string->length()];
    101     String::WriteToFlat(*string, data, 0, string->length());
    102     SimpleAsciiStringResource* resource = new SimpleAsciiStringResource(
    103         reinterpret_cast<char*>(data), string->length());
    104     result = string->MakeExternal(resource);
    105     if (result && !string->IsInternalizedString()) {
    106       HEAP->external_string_table()->AddString(*string);
    107     }
    108     if (!result) delete resource;
    109   } else {
    110     uc16* data = new uc16[string->length()];
    111     String::WriteToFlat(*string, data, 0, string->length());
    112     SimpleTwoByteStringResource* resource = new SimpleTwoByteStringResource(
    113         data, string->length());
    114     result = string->MakeExternal(resource);
    115     if (result && !string->IsInternalizedString()) {
    116       HEAP->external_string_table()->AddString(*string);
    117     }
    118     if (!result) delete resource;
    119   }
    120   if (!result) {
    121     v8::ThrowException(v8::String::New("externalizeString() failed."));
    122     return;
    123   }
    124 }
    125 
    126 
    127 void ExternalizeStringExtension::IsAscii(
    128     const v8::FunctionCallbackInfo<v8::Value>& args) {
    129   if (args.Length() != 1 || !args[0]->IsString()) {
    130     v8::ThrowException(v8::String::New(
    131         "isAsciiString() requires a single string argument."));
    132     return;
    133   }
    134   bool is_one_byte =
    135       Utils::OpenHandle(*args[0].As<v8::String>())->IsOneByteRepresentation();
    136   args.GetReturnValue().Set(is_one_byte);
    137 }
    138 
    139 
    140 void ExternalizeStringExtension::Register() {
    141   static ExternalizeStringExtension externalize_extension;
    142   static v8::DeclareExtension declaration(&externalize_extension);
    143 }
    144 
    145 } }  // namespace v8::internal
    146