diff options
| author | Ben Murdoch <benm@google.com> | 2011-05-25 10:26:03 +0100 |
|---|---|---|
| committer | Ben Murdoch <benm@google.com> | 2011-05-25 16:24:42 +0100 |
| commit | e0cee9b3ed82e2391fd85d118aeaa4ea361c687d (patch) | |
| tree | 31c7963cf0dfc88be29e765884e1f235076c03a4 /src/parser.cc | |
| parent | 1e0659c275bb392c045087af4f6b0d7565cb3d77 (diff) | |
| download | android_external_v8-e0cee9b3ed82e2391fd85d118aeaa4ea361c687d.tar.gz android_external_v8-e0cee9b3ed82e2391fd85d118aeaa4ea361c687d.tar.bz2 android_external_v8-e0cee9b3ed82e2391fd85d118aeaa4ea361c687d.zip | |
Update V8 to r7079 as required by WebKit r80534.
Change-Id: I487c152e485d5a40b68997d7c0d2f1fba5da0834
Diffstat (limited to 'src/parser.cc')
| -rw-r--r-- | src/parser.cc | 139 |
1 files changed, 99 insertions, 40 deletions
diff --git a/src/parser.cc b/src/parser.cc index 04d510f2..3c361a7e 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -803,10 +803,12 @@ void Parser::ReportMessageAt(Scanner::Location source_location, MessageLocation location(script_, source_location.beg_pos, source_location.end_pos); - Handle<JSArray> array = Factory::NewJSArray(args.length()); + Handle<FixedArray> elements = Factory::NewFixedArray(args.length()); for (int i = 0; i < args.length(); i++) { - SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i]))); + Handle<String> arg_string = Factory::NewStringFromUtf8(CStrVector(args[i])); + elements->set(i, *arg_string); } + Handle<JSArray> array = Factory::NewJSArrayWithElements(elements); Handle<Object> result = Factory::NewSyntaxError(type, array); Top::Throw(*result, &location); } @@ -818,10 +820,11 @@ void Parser::ReportMessageAt(Scanner::Location source_location, MessageLocation location(script_, source_location.beg_pos, source_location.end_pos); - Handle<JSArray> array = Factory::NewJSArray(args.length()); + Handle<FixedArray> elements = Factory::NewFixedArray(args.length()); for (int i = 0; i < args.length(); i++) { - SetElement(array, i, args[i]); + elements->set(i, *args[i]); } + Handle<JSArray> array = Factory::NewJSArrayWithElements(elements); Handle<Object> result = Factory::NewSyntaxError(type, array); Top::Throw(*result, &location); } @@ -1106,7 +1109,20 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, } Scanner::Location token_loc = scanner().peek_location(); - Statement* stat = ParseStatement(NULL, CHECK_OK); + + Statement* stat; + if (peek() == Token::FUNCTION) { + // FunctionDeclaration is only allowed in the context of SourceElements + // (Ecma 262 5th Edition, clause 14): + // SourceElement: + // Statement + // FunctionDeclaration + // Common language extension is to allow function declaration in place + // of any statement. This language extension is disabled in strict mode. + stat = ParseFunctionDeclaration(CHECK_OK); + } else { + stat = ParseStatement(NULL, CHECK_OK); + } if (stat == NULL || stat->IsEmpty()) { directive_prologue = false; // End of directive prologue. @@ -1263,8 +1279,17 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { return result; } - case Token::FUNCTION: + case Token::FUNCTION: { + // In strict mode, FunctionDeclaration is only allowed in the context + // of SourceElements. + if (temp_scope_->StrictMode()) { + ReportMessageAt(scanner().peek_location(), "strict_function", + Vector<const char*>::empty()); + *ok = false; + return NULL; + } return ParseFunctionDeclaration(ok); + } case Token::NATIVE: return ParseNativeDeclaration(ok); @@ -1515,6 +1540,11 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN, Consume(Token::VAR); } else if (peek() == Token::CONST) { Consume(Token::CONST); + if (temp_scope_->StrictMode()) { + ReportMessage("strict_const", Vector<const char*>::empty()); + *ok = false; + return NULL; + } mode = Variable::CONST; is_const = true; } else { @@ -1634,34 +1664,49 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN, if (top_scope_->is_global_scope()) { // Compute the arguments for the runtime call. - ZoneList<Expression*>* arguments = new ZoneList<Expression*>(2); - // Be careful not to assign a value to the global variable if - // we're in a with. The initialization value should not - // necessarily be stored in the global object in that case, - // which is why we need to generate a separate assignment node. + ZoneList<Expression*>* arguments = new ZoneList<Expression*>(3); arguments->Add(new Literal(name)); // we have at least 1 parameter - if (is_const || (value != NULL && !inside_with())) { - arguments->Add(value); - value = NULL; // zap the value to avoid the unnecessary assignment - } - // Construct the call to Runtime::DeclareGlobal{Variable,Const}Locally - // and add it to the initialization statement block. Note that - // this function does different things depending on if we have - // 1 or 2 parameters. CallRuntime* initialize; + if (is_const) { + arguments->Add(value); + value = NULL; // zap the value to avoid the unnecessary assignment + + // Construct the call to Runtime_InitializeConstGlobal + // and add it to the initialization statement block. + // Note that the function does different things depending on + // the number of arguments (1 or 2). initialize = - new CallRuntime( - Factory::InitializeConstGlobal_symbol(), - Runtime::FunctionForId(Runtime::kInitializeConstGlobal), - arguments); + new CallRuntime( + Factory::InitializeConstGlobal_symbol(), + Runtime::FunctionForId(Runtime::kInitializeConstGlobal), + arguments); } else { + // Add strict mode. + // We may want to pass singleton to avoid Literal allocations. + arguments->Add(NewNumberLiteral( + temp_scope_->StrictMode() ? kStrictMode : kNonStrictMode)); + + // Be careful not to assign a value to the global variable if + // we're in a with. The initialization value should not + // necessarily be stored in the global object in that case, + // which is why we need to generate a separate assignment node. + if (value != NULL && !inside_with()) { + arguments->Add(value); + value = NULL; // zap the value to avoid the unnecessary assignment + } + + // Construct the call to Runtime_InitializeVarGlobal + // and add it to the initialization statement block. + // Note that the function does different things depending on + // the number of arguments (2 or 3). initialize = - new CallRuntime( - Factory::InitializeVarGlobal_symbol(), - Runtime::FunctionForId(Runtime::kInitializeVarGlobal), - arguments); + new CallRuntime( + Factory::InitializeVarGlobal_symbol(), + Runtime::FunctionForId(Runtime::kInitializeVarGlobal), + arguments); } + block->AddStatement(new ExpressionStatement(initialize)); } @@ -2521,6 +2566,16 @@ Expression* Parser::ParseUnaryExpression(bool* ok) { } } + // "delete identifier" is a syntax error in strict mode. + if (op == Token::DELETE && temp_scope_->StrictMode()) { + VariableProxy* operand = expression->AsVariableProxy(); + if (operand != NULL && !operand->is_this()) { + ReportMessage("strict_delete", Vector<const char*>::empty()); + *ok = false; + return NULL; + } + } + return new UnaryOperation(op, expression); } else if (Token::IsCountOp(op)) { @@ -3983,12 +4038,14 @@ Handle<Object> JsonParser::ParseJson(Handle<String> script, MessageLocation location(Factory::NewScript(script), source_location.beg_pos, source_location.end_pos); - int argc = (name_opt == NULL) ? 0 : 1; - Handle<JSArray> array = Factory::NewJSArray(argc); - if (name_opt != NULL) { - SetElement(array, - 0, - Factory::NewStringFromUtf8(CStrVector(name_opt))); + Handle<JSArray> array; + if (name_opt == NULL) { + array = Factory::NewJSArray(0); + } else { + Handle<String> name = Factory::NewStringFromUtf8(CStrVector(name_opt)); + Handle<FixedArray> element = Factory::NewFixedArray(1); + element->set(0, *name); + array = Factory::NewJSArrayWithElements(element); } Handle<Object> result = Factory::NewSyntaxError(message, array); Top::Throw(*result, &location); @@ -4060,7 +4117,7 @@ Handle<Object> JsonParser::ParseJsonObject() { if (value.is_null()) return Handle<Object>::null(); uint32_t index; if (key->AsArrayIndex(&index)) { - SetOwnElement(json_object, index, value); + SetOwnElement(json_object, index, value, kNonStrictMode); } else if (key->Equals(Heap::Proto_symbol())) { // We can't remove the __proto__ accessor since it's hardcoded // in several places. Instead go along and add the value as @@ -4263,6 +4320,8 @@ RegExpTree* RegExpParser::ParseDisjunction() { capture_index); } builder->AddAtom(body); + // For compatability with JSC and ES3, we allow quantifiers after + // lookaheads, and break in all cases. break; } case '|': { @@ -4336,7 +4395,7 @@ RegExpTree* RegExpParser::ParseDisjunction() { type, captures_started()); builder = stored_state->builder(); - break; + continue; } case '[': { RegExpTree* atom = ParseCharacterClass(CHECK_FAILED); @@ -4359,11 +4418,11 @@ RegExpTree* RegExpParser::ParseDisjunction() { builder->AddAssertion( new RegExpAssertion(RegExpAssertion::NON_BOUNDARY)); continue; - // AtomEscape :: - // CharacterClassEscape - // - // CharacterClassEscape :: one of - // d D s S w W + // AtomEscape :: + // CharacterClassEscape + // + // CharacterClassEscape :: one of + // d D s S w W case 'd': case 'D': case 's': case 'S': case 'w': case 'W': { uc32 c = Next(); Advance(2); |
