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::AsciiValue(str), "externalizeString") == 0) {
     67     return v8::FunctionTemplate::New(ExternalizeStringExtension::Externalize);
     68   } else {
     69     ASSERT(strcmp(*v8::String::AsciiValue(str), "isAsciiString") == 0);
     70     return v8::FunctionTemplate::New(ExternalizeStringExtension::IsAscii);
     71   }
     72 }
     73 
     74 
     75 v8::Handle<v8::Value> ExternalizeStringExtension::Externalize(
     76     const v8::Arguments& args) {
     77   if (args.Length() < 1 || !args[0]->IsString()) {
     78     return v8::ThrowException(v8::String::New(
     79         "First parameter to externalizeString() must be a string."));
     80   }
     81   bool force_two_byte = false;
     82   if (args.Length() >= 2) {
     83     if (args[1]->IsBoolean()) {
     84       force_two_byte = args[1]->BooleanValue();
     85     } else {
     86       return v8::ThrowException(v8::String::New(
     87           "Second parameter to externalizeString() must be a boolean."));
     88     }
     89   }
     90   bool result = false;
     91   Handle<String> string = Utils::OpenHandle(*args[0].As<v8::String>());
     92   if (string->IsExternalString()) {
     93     return v8::ThrowException(v8::String::New(
     94         "externalizeString() can't externalize twice."));
     95   }
     96   if (string->IsAsciiRepresentation() && !force_two_byte) {
     97     char* data = new char[string->length()];
     98     String::WriteToFlat(*string, data, 0, string->length());
     99     SimpleAsciiStringResource* resource = new SimpleAsciiStringResource(
    100         data, string->length());
    101     result = string->MakeExternal(resource);
    102     if (result && !string->IsSymbol()) {
    103       HEAP->external_string_table()->AddString(*string);
    104     }
    105     if (!result) delete resource;
    106   } else {
    107     uc16* data = new uc16[string->length()];
    108     String::WriteToFlat(*string, data, 0, string->length());
    109     SimpleTwoByteStringResource* resource = new SimpleTwoByteStringResource(
    110         data, string->length());
    111     result = string->MakeExternal(resource);
    112     if (result && !string->IsSymbol()) {
    113       HEAP->external_string_table()->AddString(*string);
    114     }
    115     if (!result) delete resource;
    116   }
    117   if (!result) {
    118     return v8::ThrowException(v8::String::New("externalizeString() failed."));
    119   }
    120   return v8::Undefined();
    121 }
    122 
    123 
    124 v8::Handle<v8::Value> ExternalizeStringExtension::IsAscii(
    125     const v8::Arguments& args) {
    126   if (args.Length() != 1 || !args[0]->IsString()) {
    127     return v8::ThrowException(v8::String::New(
    128         "isAsciiString() requires a single string argument."));
    129   }
    130   return Utils::OpenHandle(*args[0].As<v8::String>())->IsAsciiRepresentation() ?
    131       v8::True() : v8::False();
    132 }
    133 
    134 
    135 void ExternalizeStringExtension::Register() {
    136   static ExternalizeStringExtension externalize_extension;
    137   static v8::DeclareExtension externalize_extension_declaration(
    138       &externalize_extension);
    139 }
    140 
    141 } }  // namespace v8::internal
    142