OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3892 Handle<Object> Parser::GetBoilerplateValue(Expression* expression) { | 3892 Handle<Object> Parser::GetBoilerplateValue(Expression* expression) { |
3893 if (expression->AsLiteral() != NULL) { | 3893 if (expression->AsLiteral() != NULL) { |
3894 return expression->AsLiteral()->handle(); | 3894 return expression->AsLiteral()->handle(); |
3895 } | 3895 } |
3896 if (CompileTimeValue::IsCompileTimeValue(expression)) { | 3896 if (CompileTimeValue::IsCompileTimeValue(expression)) { |
3897 return CompileTimeValue::GetValue(expression); | 3897 return CompileTimeValue::GetValue(expression); |
3898 } | 3898 } |
3899 return isolate()->factory()->undefined_value(); | 3899 return isolate()->factory()->undefined_value(); |
3900 } | 3900 } |
3901 | 3901 |
3902 // Defined in ast.cc | |
3903 bool IsEqualString(void* first, void* second); | |
3904 bool IsEqualNumber(void* first, void* second); | |
3905 | |
3906 | |
3907 // Validation per 11.1.5 Object Initialiser | 3902 // Validation per 11.1.5 Object Initialiser |
3908 class ObjectLiteralPropertyChecker { | 3903 class ObjectLiteralPropertyChecker { |
3909 public: | 3904 public: |
3910 ObjectLiteralPropertyChecker(Parser* parser, LanguageMode language_mode) : | 3905 ObjectLiteralPropertyChecker(Parser* parser, LanguageMode language_mode) : |
3911 props(&IsEqualString), | 3906 props_(Literal::Match), |
3912 elems(&IsEqualNumber), | |
3913 parser_(parser), | 3907 parser_(parser), |
3914 language_mode_(language_mode) { | 3908 language_mode_(language_mode) { |
3915 } | 3909 } |
3916 | 3910 |
3917 void CheckProperty( | 3911 void CheckProperty( |
3918 ObjectLiteral::Property* property, | 3912 ObjectLiteral::Property* property, |
3919 Scanner::Location loc, | 3913 Scanner::Location loc, |
3920 bool* ok); | 3914 bool* ok); |
3921 | 3915 |
3922 private: | 3916 private: |
3923 enum PropertyKind { | 3917 enum PropertyKind { |
3924 kGetAccessor = 0x01, | 3918 kGetAccessor = 0x01, |
3925 kSetAccessor = 0x02, | 3919 kSetAccessor = 0x02, |
3926 kAccessor = kGetAccessor | kSetAccessor, | 3920 kAccessor = kGetAccessor | kSetAccessor, |
3927 kData = 0x04 | 3921 kData = 0x04 |
3928 }; | 3922 }; |
3929 | 3923 |
3930 static intptr_t GetPropertyKind(ObjectLiteral::Property* property) { | 3924 static intptr_t GetPropertyKind(ObjectLiteral::Property* property) { |
3931 switch (property->kind()) { | 3925 switch (property->kind()) { |
3932 case ObjectLiteral::Property::GETTER: | 3926 case ObjectLiteral::Property::GETTER: |
3933 return kGetAccessor; | 3927 return kGetAccessor; |
3934 case ObjectLiteral::Property::SETTER: | 3928 case ObjectLiteral::Property::SETTER: |
3935 return kSetAccessor; | 3929 return kSetAccessor; |
3936 default: | 3930 default: |
3937 return kData; | 3931 return kData; |
3938 } | 3932 } |
3939 } | 3933 } |
3940 | 3934 |
3941 HashMap props; | 3935 HashMap props_; |
3942 HashMap elems; | |
3943 Parser* parser_; | 3936 Parser* parser_; |
3944 LanguageMode language_mode_; | 3937 LanguageMode language_mode_; |
3945 }; | 3938 }; |
3946 | 3939 |
3947 | 3940 |
3948 void ObjectLiteralPropertyChecker::CheckProperty( | 3941 void ObjectLiteralPropertyChecker::CheckProperty( |
3949 ObjectLiteral::Property* property, | 3942 ObjectLiteral::Property* property, |
3950 Scanner::Location loc, | 3943 Scanner::Location loc, |
3951 bool* ok) { | 3944 bool* ok) { |
3952 | |
3953 ASSERT(property != NULL); | 3945 ASSERT(property != NULL); |
3954 | 3946 Literal* literal = property->key(); |
3955 Literal* lit = property->key(); | 3947 HashMap::Entry* entry = props_.Lookup(literal, literal->Hash(), true); |
3956 Handle<Object> handle = lit->handle(); | |
3957 | |
3958 uint32_t hash; | |
3959 HashMap* map; | |
3960 void* key; | |
3961 | |
3962 if (handle->IsSymbol()) { | |
3963 Handle<String> name(String::cast(*handle)); | |
3964 if (name->AsArrayIndex(&hash)) { | |
3965 Handle<Object> key_handle = FACTORY->NewNumberFromUint(hash); | |
3966 key = key_handle.location(); | |
3967 map = &elems; | |
3968 } else { | |
3969 key = handle.location(); | |
3970 hash = name->Hash(); | |
3971 map = &props; | |
3972 } | |
3973 } else if (handle->ToArrayIndex(&hash)) { | |
3974 key = handle.location(); | |
3975 map = &elems; | |
3976 } else { | |
3977 ASSERT(handle->IsNumber()); | |
3978 double num = handle->Number(); | |
3979 char arr[100]; | |
3980 Vector<char> buffer(arr, ARRAY_SIZE(arr)); | |
3981 const char* str = DoubleToCString(num, buffer); | |
3982 Handle<String> name = FACTORY->NewStringFromAscii(CStrVector(str)); | |
3983 key = name.location(); | |
3984 hash = name->Hash(); | |
3985 map = &props; | |
3986 } | |
3987 | |
3988 // Lookup property previously defined, if any. | |
3989 HashMap::Entry* entry = map->Lookup(key, hash, true); | |
3990 intptr_t prev = reinterpret_cast<intptr_t> (entry->value); | 3948 intptr_t prev = reinterpret_cast<intptr_t> (entry->value); |
3991 intptr_t curr = GetPropertyKind(property); | 3949 intptr_t curr = GetPropertyKind(property); |
3992 | 3950 |
3993 // Duplicate data properties are illegal in strict or extended mode. | 3951 // Duplicate data properties are illegal in strict or extended mode. |
3994 if (language_mode_ != CLASSIC_MODE && (curr & prev & kData) != 0) { | 3952 if (language_mode_ != CLASSIC_MODE && (curr & prev & kData) != 0) { |
3995 parser_->ReportMessageAt(loc, "strict_duplicate_property", | 3953 parser_->ReportMessageAt(loc, "strict_duplicate_property", |
3996 Vector<const char*>::empty()); | 3954 Vector<const char*>::empty()); |
3997 *ok = false; | 3955 *ok = false; |
3998 return; | 3956 return; |
3999 } | 3957 } |
(...skipping 2041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6041 ASSERT(info->isolate()->has_pending_exception()); | 5999 ASSERT(info->isolate()->has_pending_exception()); |
6042 } else { | 6000 } else { |
6043 result = parser.ParseProgram(info); | 6001 result = parser.ParseProgram(info); |
6044 } | 6002 } |
6045 } | 6003 } |
6046 info->SetFunction(result); | 6004 info->SetFunction(result); |
6047 return (result != NULL); | 6005 return (result != NULL); |
6048 } | 6006 } |
6049 | 6007 |
6050 } } // namespace v8::internal | 6008 } } // namespace v8::internal |
OLD | NEW |