Fix building with clang

BUG=v8:1912

Review URL: https://chromiumcodereview.appspot.com/9285013

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10492 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent be288cf2
...@@ -295,7 +295,7 @@ ...@@ -295,7 +295,7 @@
'-O3', '-O3',
], ],
'conditions': [ 'conditions': [
[ 'gcc_version==44', { [ 'gcc_version==44 and clang==0', {
'cflags': [ 'cflags': [
# Avoid crashes with gcc 4.4 in the v8 test suite. # Avoid crashes with gcc 4.4 in the v8 test suite.
'-fno-tree-vrp', '-fno-tree-vrp',
......
...@@ -300,11 +300,13 @@ const DwVfpRegister d13 = { 13 }; ...@@ -300,11 +300,13 @@ const DwVfpRegister d13 = { 13 };
const DwVfpRegister d14 = { 14 }; const DwVfpRegister d14 = { 14 };
const DwVfpRegister d15 = { 15 }; const DwVfpRegister d15 = { 15 };
// Aliases for double registers. // Aliases for double registers. Defined using #define instead of
static const DwVfpRegister& kFirstCalleeSavedDoubleReg = d8; // "static const DwVfpRegister&" because Clang complains otherwise when a
static const DwVfpRegister& kLastCalleeSavedDoubleReg = d15; // compilation unit that includes this header doesn't use the variables.
static const DwVfpRegister& kDoubleRegZero = d14; #define kFirstCalleeSavedDoubleReg d8
static const DwVfpRegister& kScratchDoubleReg = d15; #define kLastCalleeSavedDoubleReg d15
#define kDoubleRegZero d14
#define kScratchDoubleReg d15
// Coprocessor register // Coprocessor register
......
...@@ -1923,12 +1923,11 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement( ...@@ -1923,12 +1923,11 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
HLoadKeyedSpecializedArrayElement* instr) { HLoadKeyedSpecializedArrayElement* instr) {
ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
Representation representation(instr->representation());
ASSERT( ASSERT(
(representation.IsInteger32() && (instr->representation().IsInteger32() &&
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) && (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
(representation.IsDouble() && (instr->representation().IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->key()->representation().IsInteger32()); ASSERT(instr->key()->representation().IsInteger32());
...@@ -1988,13 +1987,12 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement( ...@@ -1988,13 +1987,12 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
HStoreKeyedSpecializedArrayElement* instr) { HStoreKeyedSpecializedArrayElement* instr) {
Representation representation(instr->value()->representation());
ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
ASSERT( ASSERT(
(representation.IsInteger32() && (instr->value()->representation().IsInteger32() &&
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) && (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
(representation.IsDouble() && (instr->value()->representation().IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->external_pointer()->representation().IsExternal()); ASSERT(instr->external_pointer()->representation().IsExternal());
......
...@@ -2008,12 +2008,11 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement( ...@@ -2008,12 +2008,11 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
HLoadKeyedSpecializedArrayElement* instr) { HLoadKeyedSpecializedArrayElement* instr) {
ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
Representation representation(instr->representation());
ASSERT( ASSERT(
(representation.IsInteger32() && (instr->representation().IsInteger32() &&
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) && (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
(representation.IsDouble() && (instr->representation().IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->key()->representation().IsInteger32()); ASSERT(instr->key()->representation().IsInteger32());
...@@ -2076,13 +2075,12 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement( ...@@ -2076,13 +2075,12 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
HStoreKeyedSpecializedArrayElement* instr) { HStoreKeyedSpecializedArrayElement* instr) {
Representation representation(instr->value()->representation());
ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
ASSERT( ASSERT(
(representation.IsInteger32() && (instr->value()->representation().IsInteger32() &&
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) && (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
(representation.IsDouble() && (instr->value()->representation().IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->external_pointer()->representation().IsExternal()); ASSERT(instr->external_pointer()->representation().IsExternal());
......
// Copyright 2011 the V8 project authors. All rights reserved. // Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -1081,36 +1081,6 @@ void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) { ...@@ -1081,36 +1081,6 @@ void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) {
PutSection(static_cast<int>(integer & 0x7f), "IntLastPart"); PutSection(static_cast<int>(integer & 0x7f), "IntLastPart");
} }
#ifdef DEBUG
void Deserializer::Synchronize(const char* tag) {
int data = source_->Get();
// If this assert fails then that indicates that you have a mismatch between
// the number of GC roots when serializing and deserializing.
ASSERT_EQ(kSynchronize, data);
do {
int character = source_->Get();
if (character == 0) break;
if (FLAG_debug_serialization) {
PrintF("%c", character);
}
} while (true);
if (FLAG_debug_serialization) {
PrintF("\n");
}
}
void Serializer::Synchronize(const char* tag) {
sink_->Put(kSynchronize, tag);
int character;
do {
character = *tag++;
sink_->PutSection(character, "TagCharacter");
} while (character != 0);
}
#endif
Serializer::Serializer(SnapshotByteSink* sink) Serializer::Serializer(SnapshotByteSink* sink)
: sink_(sink), : sink_(sink),
......
...@@ -341,10 +341,6 @@ class Deserializer: public SerializerDeserializer { ...@@ -341,10 +341,6 @@ class Deserializer: public SerializerDeserializer {
// Deserialize a single object and the objects reachable from it. // Deserialize a single object and the objects reachable from it.
void DeserializePartial(Object** root); void DeserializePartial(Object** root);
#ifdef DEBUG
virtual void Synchronize(const char* tag);
#endif
private: private:
virtual void VisitPointers(Object** start, Object** end); virtual void VisitPointers(Object** start, Object** end);
...@@ -485,9 +481,6 @@ class Serializer : public SerializerDeserializer { ...@@ -485,9 +481,6 @@ class Serializer : public SerializerDeserializer {
SerializationAddressMapper* address_mapper() { return &address_mapper_; } SerializationAddressMapper* address_mapper() { return &address_mapper_; }
void PutRoot( void PutRoot(
int index, HeapObject* object, HowToCode how, WhereToPoint where); int index, HeapObject* object, HowToCode how, WhereToPoint where);
#ifdef DEBUG
virtual void Synchronize(const char* tag);
#endif
protected: protected:
static const int kInvalidRootIndex = -1; static const int kInvalidRootIndex = -1;
......
...@@ -1918,12 +1918,11 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement( ...@@ -1918,12 +1918,11 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
HLoadKeyedSpecializedArrayElement* instr) { HLoadKeyedSpecializedArrayElement* instr) {
ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
Representation representation(instr->representation());
ASSERT( ASSERT(
(representation.IsInteger32() && (instr->representation().IsInteger32() &&
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) && (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
(representation.IsDouble() && (instr->representation().IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->key()->representation().IsInteger32()); ASSERT(instr->key()->representation().IsInteger32());
...@@ -1982,13 +1981,12 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement( ...@@ -1982,13 +1981,12 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
HStoreKeyedSpecializedArrayElement* instr) { HStoreKeyedSpecializedArrayElement* instr) {
Representation representation(instr->value()->representation());
ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
ASSERT( ASSERT(
(representation.IsInteger32() && (instr->value()->representation().IsInteger32() &&
(elements_kind != EXTERNAL_FLOAT_ELEMENTS) && (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
(elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
(representation.IsDouble() && (instr->value()->representation().IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->external_pointer()->representation().IsExternal()); ASSERT(instr->external_pointer()->representation().IsExternal());
......
This diff is collapsed.
// Copyright 2011 the V8 project authors. All rights reserved. // Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -270,8 +270,7 @@ TEST(UncaughtThrow) { ...@@ -270,8 +270,7 @@ TEST(UncaughtThrow) {
CHECK(!fun.is_null()); CHECK(!fun.is_null());
bool has_pending_exception; bool has_pending_exception;
Handle<JSObject> global(Isolate::Current()->context()->global()); Handle<JSObject> global(Isolate::Current()->context()->global());
Handle<Object> result( Execution::Call(fun, global, 0, NULL, &has_pending_exception);
Execution::Call(fun, global, 0, NULL, &has_pending_exception));
CHECK(has_pending_exception); CHECK(has_pending_exception);
CHECK_EQ(42.0, Isolate::Current()->pending_exception()-> CHECK_EQ(42.0, Isolate::Current()->pending_exception()->
ToObjectChecked()->Number()); ToObjectChecked()->Number());
......
// Copyright 2011 the V8 project authors. All rights reserved. // Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -856,7 +856,7 @@ static void DebugEventRemoveBreakPoint(v8::DebugEvent event, ...@@ -856,7 +856,7 @@ static void DebugEventRemoveBreakPoint(v8::DebugEvent event,
if (event == v8::Break) { if (event == v8::Break) {
break_point_hit_count++; break_point_hit_count++;
v8::Handle<v8::Function> fun(v8::Handle<v8::Function>::Cast(data)); CHECK(data->IsFunction());
ClearBreakPoint(debug_event_remove_break_point); ClearBreakPoint(debug_event_remove_break_point);
} }
} }
...@@ -1447,8 +1447,7 @@ TEST(BreakPointSurviveGC) { ...@@ -1447,8 +1447,7 @@ TEST(BreakPointSurviveGC) {
// Test IC store break point with garbage collection. // Test IC store break point with garbage collection.
{ {
v8::Local<v8::Function> bar( CompileFunction(&env, "function foo(){}", "foo");
CompileFunction(&env, "function foo(){}", "foo"));
foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); foo = CompileFunction(&env, "function foo(){bar=0;}", "foo");
SetBreakPoint(foo, 0); SetBreakPoint(foo, 0);
} }
...@@ -1456,8 +1455,7 @@ TEST(BreakPointSurviveGC) { ...@@ -1456,8 +1455,7 @@ TEST(BreakPointSurviveGC) {
// Test IC load break point with garbage collection. // Test IC load break point with garbage collection.
{ {
v8::Local<v8::Function> bar( CompileFunction(&env, "function foo(){}", "foo");
CompileFunction(&env, "function foo(){}", "foo"));
foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo");
SetBreakPoint(foo, 0); SetBreakPoint(foo, 0);
} }
...@@ -1465,8 +1463,7 @@ TEST(BreakPointSurviveGC) { ...@@ -1465,8 +1463,7 @@ TEST(BreakPointSurviveGC) {
// Test IC call break point with garbage collection. // Test IC call break point with garbage collection.
{ {
v8::Local<v8::Function> bar( CompileFunction(&env, "function foo(){}", "foo");
CompileFunction(&env, "function foo(){}", "foo"));
foo = CompileFunction(&env, foo = CompileFunction(&env,
"function bar(){};function foo(){bar();}", "function bar(){};function foo(){bar();}",
"foo"); "foo");
...@@ -1476,8 +1473,7 @@ TEST(BreakPointSurviveGC) { ...@@ -1476,8 +1473,7 @@ TEST(BreakPointSurviveGC) {
// Test return break point with garbage collection. // Test return break point with garbage collection.
{ {
v8::Local<v8::Function> bar( CompileFunction(&env, "function foo(){}", "foo");
CompileFunction(&env, "function foo(){}", "foo"));
foo = CompileFunction(&env, "function foo(){}", "foo"); foo = CompileFunction(&env, "function foo(){}", "foo");
SetBreakPoint(foo, 0); SetBreakPoint(foo, 0);
} }
...@@ -1485,8 +1481,7 @@ TEST(BreakPointSurviveGC) { ...@@ -1485,8 +1481,7 @@ TEST(BreakPointSurviveGC) {
// Test non IC break point with garbage collection. // Test non IC break point with garbage collection.
{ {
v8::Local<v8::Function> bar( CompileFunction(&env, "function foo(){}", "foo");
CompileFunction(&env, "function foo(){}", "foo"));
foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo"); foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo");
SetBreakPoint(foo, 0); SetBreakPoint(foo, 0);
} }
...@@ -3751,8 +3746,7 @@ TEST(BreakOnException) { ...@@ -3751,8 +3746,7 @@ TEST(BreakOnException) {
v8::internal::Isolate::Current()->TraceException(false); v8::internal::Isolate::Current()->TraceException(false);
// Create functions for testing break on exception. // Create functions for testing break on exception.
v8::Local<v8::Function> throws( CompileFunction(&env, "function throws(){throw 1;}", "throws");
CompileFunction(&env, "function throws(){throw 1;}", "throws"));
v8::Local<v8::Function> caught = v8::Local<v8::Function> caught =
CompileFunction(&env, CompileFunction(&env,
"function caught(){try {throws();} catch(e) {};}", "function caught(){try {throws();} catch(e) {};}",
...@@ -5549,8 +5543,6 @@ TEST(DebuggerUnload) { ...@@ -5549,8 +5543,6 @@ TEST(DebuggerUnload) {
// Get the test functions again. // Get the test functions again.
v8::Local<v8::Function> foo(v8::Local<v8::Function>::Cast( v8::Local<v8::Function> foo(v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::New("foo")))); env->Global()->Get(v8::String::New("foo"))));
v8::Local<v8::Function> bar(v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::New("foo"))));
foo->Call(env->Global(), 0, NULL); foo->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count); CHECK_EQ(0, break_point_hit_count);
...@@ -6028,6 +6020,8 @@ TEST(DebugGetLoadedScripts) { ...@@ -6028,6 +6020,8 @@ TEST(DebugGetLoadedScripts) {
EmptyExternalStringResource source_ext_str; EmptyExternalStringResource source_ext_str;
v8::Local<v8::String> source = v8::String::NewExternal(&source_ext_str); v8::Local<v8::String> source = v8::String::NewExternal(&source_ext_str);
v8::Handle<v8::Script> evil_script(v8::Script::Compile(source)); v8::Handle<v8::Script> evil_script(v8::Script::Compile(source));
// "use" evil_script to make the compiler happy.
(void) evil_script;
Handle<i::ExternalTwoByteString> i_source( Handle<i::ExternalTwoByteString> i_source(
i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source))); i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source)));
// This situation can happen if source was an external string disposed // This situation can happen if source was an external string disposed
...@@ -6675,7 +6669,7 @@ static void BreakMessageHandler(const v8::Debug::Message& message) { ...@@ -6675,7 +6669,7 @@ static void BreakMessageHandler(const v8::Debug::Message& message) {
break_point_hit_count++; break_point_hit_count++;
v8::HandleScope scope; v8::HandleScope scope;
v8::Handle<v8::String> json(message.GetJSON()); message.GetJSON();
SendContinueCommand(); SendContinueCommand();
} else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) { } else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) {
...@@ -6686,7 +6680,7 @@ static void BreakMessageHandler(const v8::Debug::Message& message) { ...@@ -6686,7 +6680,7 @@ static void BreakMessageHandler(const v8::Debug::Message& message) {
isolate->stack_guard()->DebugBreak(); isolate->stack_guard()->DebugBreak();
// Force serialization to trigger some internal JS execution. // Force serialization to trigger some internal JS execution.
v8::Handle<v8::String> json(message.GetJSON()); message.GetJSON();
// Restore previous state. // Restore previous state.
if (is_debug_break) { if (is_debug_break) {
......
// Copyright 2007-2010 the V8 project authors. All rights reserved. // Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -237,7 +237,7 @@ TEST(DeoptimizeRecursive) { ...@@ -237,7 +237,7 @@ TEST(DeoptimizeRecursive) {
v8::Local<v8::Function> fun = v8::Local<v8::Function> fun =
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
Handle<v8::internal::JSFunction> f(v8::Utils::OpenHandle(*fun)); CHECK(!fun.IsEmpty());
} }
......
// Copyright 2011 the V8 project authors. All rights reserved. // Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -230,7 +230,7 @@ TEST(Preparsing) { ...@@ -230,7 +230,7 @@ TEST(Preparsing) {
CHECK_EQ(11, error_location.end_pos); CHECK_EQ(11, error_location.end_pos);
// Should not crash. // Should not crash.
const char* message = pre_impl->BuildMessage(); const char* message = pre_impl->BuildMessage();
i::Vector<const char*> args(pre_impl->BuildArgs()); pre_impl->BuildArgs();
CHECK_GT(strlen(message), 0); CHECK_GT(strlen(message), 0);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment