Skip to content

Commit 81f5ed5

Browse files
committed
Upgrade V8 to 2.3.5
1 parent 7db5c8a commit 81f5ed5

File tree

10 files changed

+224
-27
lines changed

10 files changed

+224
-27
lines changed

deps/v8/ChangeLog

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
2010-08-04: Version 2.3.5
2+
3+
Added support for ES5 property names. Object initialisers and
4+
dot-notation property access now allows keywords. Also allowed
5+
non-identifiers after "get" or "set" in an object initialiser.
6+
7+
Randomize the addresses of allocated executable memory on Windows.
8+
9+
110
2010-08-02: Version 2.3.4
211

312
Fixed problems in implementation of ES5 function.prototype.bind.

deps/v8/src/parser.cc

+45-13
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ class Parser {
265265
Literal* GetLiteralNumber(double value);
266266

267267
Handle<String> ParseIdentifier(bool* ok);
268+
Handle<String> ParseIdentifierName(bool* ok);
268269
Handle<String> ParseIdentifierOrGetOrSet(bool* is_get,
269270
bool* is_set,
270271
bool* ok);
@@ -3121,7 +3122,7 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
31213122
case Token::PERIOD: {
31223123
Consume(Token::PERIOD);
31233124
int pos = scanner().location().beg_pos;
3124-
Handle<String> name = ParseIdentifier(CHECK_OK);
3125+
Handle<String> name = ParseIdentifierName(CHECK_OK);
31253126
result = factory()->NewProperty(result, NEW(Literal(name)), pos);
31263127
break;
31273128
}
@@ -3207,7 +3208,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
32073208
case Token::PERIOD: {
32083209
Consume(Token::PERIOD);
32093210
int pos = scanner().location().beg_pos;
3210-
Handle<String> name = ParseIdentifier(CHECK_OK);
3211+
Handle<String> name = ParseIdentifierName(CHECK_OK);
32113212
result = factory()->NewProperty(result, NEW(Literal(name)), pos);
32123213
break;
32133214
}
@@ -3586,8 +3587,8 @@ void Parser::BuildObjectLiteralConstantProperties(
35863587
Expression* Parser::ParseObjectLiteral(bool* ok) {
35873588
// ObjectLiteral ::
35883589
// '{' (
3589-
// ((Identifier | String | Number) ':' AssignmentExpression)
3590-
// | (('get' | 'set') FunctionLiteral)
3590+
// ((IdentifierName | String | Number) ':' AssignmentExpression)
3591+
// | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
35913592
// )*[','] '}'
35923593

35933594
ZoneListWrapper<ObjectLiteral::Property> properties =
@@ -3597,7 +3598,8 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
35973598
Expect(Token::LBRACE, CHECK_OK);
35983599
while (peek() != Token::RBRACE) {
35993600
Literal* key = NULL;
3600-
switch (peek()) {
3601+
Token::Value next = peek();
3602+
switch (next) {
36013603
case Token::IDENTIFIER: {
36023604
// Store identifier keys as literal symbols to avoid
36033605
// resolving them when compiling code for the object
@@ -3608,15 +3610,26 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
36083610
ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
36093611
if (is_getter || is_setter) {
36103612
// Special handling of getter and setter syntax.
3611-
if (peek() == Token::IDENTIFIER) {
3612-
Handle<String> name = ParseIdentifier(CHECK_OK);
3613+
Handle<String> name;
3614+
next = peek();
3615+
if (next == Token::IDENTIFIER ||
3616+
next == Token::STRING ||
3617+
next == Token::NUMBER ||
3618+
Token::IsKeyword(next)) {
3619+
Consume(next);
3620+
Handle<String> name =
3621+
factory()->LookupSymbol(scanner_.literal_string(),
3622+
scanner_.literal_length());
36133623
FunctionLiteral* value =
3614-
ParseFunctionLiteral(name, RelocInfo::kNoPosition,
3615-
DECLARATION, CHECK_OK);
3624+
ParseFunctionLiteral(name,
3625+
RelocInfo::kNoPosition,
3626+
DECLARATION,
3627+
CHECK_OK);
36163628
ObjectLiteral::Property* property =
36173629
NEW(ObjectLiteral::Property(is_getter, value));
3618-
if (IsBoilerplateProperty(property))
3630+
if (IsBoilerplateProperty(property)) {
36193631
number_of_boilerplate_properties++;
3632+
}
36203633
properties.Add(property);
36213634
if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
36223635
continue; // restart the while
@@ -3625,14 +3638,20 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
36253638
key = NEW(Literal(id));
36263639
break;
36273640
}
3628-
3641+
#define CASE_KEYWORD(name, ignore1, ignore2) \
3642+
case Token::name:
3643+
TOKEN_LIST(IGNORE_TOKEN, CASE_KEYWORD, IGNORE_TOKEN)
3644+
#undef CASE_KEYWORD
3645+
// FALLTHROUGH - keyword tokens fall through to the same code as strings.
36293646
case Token::STRING: {
3630-
Consume(Token::STRING);
3647+
Consume(next);
36313648
Handle<String> string =
36323649
factory()->LookupSymbol(scanner_.literal_string(),
36333650
scanner_.literal_length());
36343651
uint32_t index;
3635-
if (!string.is_null() && string->AsArrayIndex(&index)) {
3652+
if (next == Token::STRING &&
3653+
!string.is_null() &&
3654+
string->AsArrayIndex(&index)) {
36363655
key = NewNumberLiteral(index);
36373656
} else {
36383657
key = NEW(Literal(string));
@@ -4008,6 +4027,19 @@ Handle<String> Parser::ParseIdentifier(bool* ok) {
40084027
scanner_.literal_length());
40094028
}
40104029

4030+
4031+
Handle<String> Parser::ParseIdentifierName(bool* ok) {
4032+
Token::Value next = Next();
4033+
if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) {
4034+
ReportUnexpectedToken(next);
4035+
*ok = false;
4036+
return Handle<String>();
4037+
}
4038+
return factory()->LookupSymbol(scanner_.literal_string(),
4039+
scanner_.literal_length());
4040+
}
4041+
4042+
40114043
// This function reads an identifier and determines whether or not it
40124044
// is 'get' or 'set'. The reason for not using ParseIdentifier and
40134045
// checking on the output is that this involves heap allocation which

deps/v8/src/platform-linux.cc

+1
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ size_t OS::AllocateAlignment() {
236236
void* OS::Allocate(const size_t requested,
237237
size_t* allocated,
238238
bool is_executable) {
239+
// TODO(805): Port randomization of allocated executable memory to Linux.
239240
const size_t msize = RoundUp(requested, sysconf(_SC_PAGESIZE));
240241
int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
241242
void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

deps/v8/src/platform-win32.cc

+27-1
Original file line numberDiff line numberDiff line change
@@ -838,12 +838,38 @@ size_t OS::AllocateAlignment() {
838838
void* OS::Allocate(const size_t requested,
839839
size_t* allocated,
840840
bool is_executable) {
841+
// The address range used to randomize RWX allocations in OS::Allocate
842+
// Try not to map pages into the default range that windows loads DLLs
843+
// Note: This does not guarantee RWX regions will be within the
844+
// range kAllocationRandomAddressMin to kAllocationRandomAddressMax
845+
#ifdef V8_HOST_ARCH_64_BIT
846+
static const intptr_t kAllocationRandomAddressMin = 0x0000000080000000;
847+
static const intptr_t kAllocationRandomAddressMax = 0x000004FFFFFFFFFF;
848+
#else
849+
static const intptr_t kAllocationRandomAddressMin = 0x04000000;
850+
static const intptr_t kAllocationRandomAddressMax = 0x4FFFFFFF;
851+
#endif
852+
841853
// VirtualAlloc rounds allocated size to page size automatically.
842854
size_t msize = RoundUp(requested, static_cast<int>(GetPageSize()));
855+
intptr_t address = NULL;
843856

844857
// Windows XP SP2 allows Data Excution Prevention (DEP).
845858
int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
846-
LPVOID mbase = VirtualAlloc(NULL, msize, MEM_COMMIT | MEM_RESERVE, prot);
859+
860+
// For exectutable pages try and randomize the allocation address
861+
if (prot == PAGE_EXECUTE_READWRITE && msize >= Page::kPageSize) {
862+
address = (V8::Random() << kPageSizeBits) | kAllocationRandomAddressMin;
863+
address &= kAllocationRandomAddressMax;
864+
}
865+
866+
LPVOID mbase = VirtualAlloc(reinterpret_cast<void *>(address),
867+
msize,
868+
MEM_COMMIT | MEM_RESERVE,
869+
prot);
870+
if (mbase == NULL && address != NULL)
871+
mbase = VirtualAlloc(NULL, msize, MEM_COMMIT | MEM_RESERVE, prot);
872+
847873
if (mbase == NULL) {
848874
LOG(StringEvent("OS::Allocate", "VirtualAlloc failed"));
849875
return NULL;

deps/v8/src/runtime.cc

+5-6
Original file line numberDiff line numberDiff line change
@@ -305,14 +305,13 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
305305
}
306306
Handle<Object> result;
307307
uint32_t element_index = 0;
308-
if (key->IsSymbol()) {
309-
// If key is a symbol it is not an array element.
310-
Handle<String> name(String::cast(*key));
311-
ASSERT(!name->AsArrayIndex(&element_index));
312-
result = SetProperty(boilerplate, name, value, NONE);
313-
} else if (key->ToArrayIndex(&element_index)) {
308+
if (key->ToArrayIndex(&element_index)) {
314309
// Array index (uint32).
315310
result = SetElement(boilerplate, element_index, value);
311+
} else if (key->IsSymbol()) {
312+
// The key is not an array index.
313+
Handle<String> name(String::cast(*key));
314+
result = SetProperty(boilerplate, name, value, NONE);
316315
} else {
317316
// Non-uint32 number.
318317
ASSERT(key->IsNumber());

deps/v8/src/token.cc

+8
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,12 @@ int8_t Token::precedence_[NUM_TOKENS] = {
5353
#undef T
5454

5555

56+
#define KT(a, b, c) 'T',
57+
#define KK(a, b, c) 'K',
58+
const char Token::token_type[] = {
59+
TOKEN_LIST(KT, KK, IGNORE_TOKEN)
60+
};
61+
#undef KT
62+
#undef KK
63+
5664
} } // namespace v8::internal

deps/v8/src/token.h

+5
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ class Token {
220220
}
221221

222222
// Predicates
223+
static bool IsKeyword(Value tok) {
224+
return token_type[tok] == 'K';
225+
}
226+
223227
static bool IsAssignmentOp(Value tok) {
224228
return INIT_VAR <= tok && tok <= ASSIGN_MOD;
225229
}
@@ -263,6 +267,7 @@ class Token {
263267
static const char* name_[NUM_TOKENS];
264268
static const char* string_[NUM_TOKENS];
265269
static int8_t precedence_[NUM_TOKENS];
270+
static const char token_type[NUM_TOKENS];
266271
};
267272

268273
} } // namespace v8::internal

deps/v8/src/version.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
// cannot be changed without changing the SCons build script.
3535
#define MAJOR_VERSION 2
3636
#define MINOR_VERSION 3
37-
#define BUILD_NUMBER 4
38-
#define PATCH_LEVEL 1
37+
#define BUILD_NUMBER 5
38+
#define PATCH_LEVEL 0
3939
#define CANDIDATE_VERSION false
4040

4141
// Define SONAME to have the SCons build the put a specific SONAME into the

deps/v8/test/mjsunit/object-literal.js

+107
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,110 @@ a = makeRegexpInObject();
103103
b = makeRegexpInObject();
104104
assertTrue(a.a.b === b.a.b);
105105
assertFalse(a.a.c === b.a.c);
106+
107+
108+
// Test keywords valid as property names in initializers and dot-access.
109+
var keywords = [
110+
"break",
111+
"case",
112+
"catch",
113+
"const",
114+
"continue",
115+
"debugger",
116+
"default",
117+
"delete",
118+
"do",
119+
"else",
120+
"false",
121+
"finally",
122+
"for",
123+
"function",
124+
"if",
125+
"in",
126+
"instanceof",
127+
"native",
128+
"new",
129+
"null",
130+
"return",
131+
"switch",
132+
"this",
133+
"throw",
134+
"true",
135+
"try",
136+
"typeof",
137+
"var",
138+
"void",
139+
"while",
140+
"with",
141+
];
142+
143+
function testKeywordProperty(keyword) {
144+
try {
145+
// Sanity check that what we get is a keyword.
146+
eval("var " + keyword + " = 42;");
147+
assertUnreachable("Not a keyword: " + keyword);
148+
} catch (e) { }
149+
150+
// Simple property, read and write.
151+
var x = eval("({" + keyword + ": 42})");
152+
assertEquals(42, x[keyword]);
153+
assertEquals(42, eval("x." + keyword));
154+
eval("x." + keyword + " = 37");
155+
assertEquals(37, x[keyword]);
156+
assertEquals(37, eval("x." + keyword));
157+
158+
// Getter/setter property, read and write.
159+
var y = eval("({value : 42, get " + keyword + "(){return this.value}," +
160+
" set " + keyword + "(v) { this.value = v; }})");
161+
assertEquals(42, y[keyword]);
162+
assertEquals(42, eval("y." + keyword));
163+
eval("y." + keyword + " = 37");
164+
assertEquals(37, y[keyword]);
165+
assertEquals(37, eval("y." + keyword));
166+
167+
// Quoted keyword works is read back by unquoted as well.
168+
var z = eval("({\"" + keyword + "\": 42})");
169+
assertEquals(42, z[keyword]);
170+
assertEquals(42, eval("z." + keyword));
171+
172+
// Function property, called.
173+
var was_called;
174+
function test_call() { this.was_called = true; was_called = true; }
175+
var w = eval("({" + keyword + ": test_call, was_called: false})");
176+
eval("w." + keyword + "();");
177+
assertTrue(was_called);
178+
assertTrue(w.was_called);
179+
180+
// Function property, constructed.
181+
function construct() { this.constructed = true; }
182+
var v = eval("({" + keyword + ": construct})");
183+
var vo = eval("new v." + keyword + "()");
184+
assertTrue(vo instanceof construct);
185+
assertTrue(vo.constructed);
186+
}
187+
188+
for (var i = 0; i < keywords.length; i++) {
189+
testKeywordProperty(keywords[i]);
190+
}
191+
192+
// Test getter and setter properties with string/number literal names.
193+
194+
var obj = {get 42() { return 42; },
195+
get 3.14() { return "PI"; },
196+
get "PI"() { return 3.14; },
197+
readback: 0,
198+
set 37(v) { this.readback = v; },
199+
set 1.44(v) { this.readback = v; },
200+
set "Poo"(v) { this.readback = v; }}
201+
202+
assertEquals(42, obj[42]);
203+
assertEquals("PI", obj[3.14]);
204+
assertEquals(3.14, obj["PI"]);
205+
obj[37] = "t1";
206+
assertEquals("t1", obj.readback);
207+
obj[1.44] = "t2";
208+
assertEquals("t2", obj.readback);
209+
obj["Poo"] = "t3";
210+
assertEquals("t3", obj.readback);
211+
212+

deps/v8/test/sputnik/sputnik.status

+15-5
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,6 @@ S15.5.4.11_D1.1_T1: PASS || FAIL_OK
158158
S15.5.4.11_D1.1_T3: PASS || FAIL_OK
159159
S12.6.4_D1: PASS || FAIL_OK
160160

161-
# We deliberately don't throw type errors when iterating through the
162-
# undefined object
163-
S9.9_A1: FAIL_OK
164-
S9.9_A2: FAIL_OK
165-
166161
# We allow function declarations within statements
167162
S12.5_A9_T1: FAIL_OK
168163
S12.5_A9_T2: FAIL_OK
@@ -184,6 +179,21 @@ S15.3.4.2_A1_T1: FAIL_OK
184179
S8.5_A2.2: PASS, FAIL if $system == linux, FAIL if $system == macos
185180
S8.5_A2.1: PASS, FAIL if $system == linux, FAIL if $system == macos
186181

182+
##################### ES3 TESTS #########################
183+
# These tests check for ES3 semantics, and differ from ES5.
184+
# When we follow ES5 semantics, it's ok to fail the test.
185+
186+
# Allow keywords as names of properties in object initialisers and
187+
# in dot-notation property access.
188+
S11.1.5_A4.1: FAIL_OK
189+
S11.1.5_A4.2: FAIL_OK
190+
191+
# Don't throw type errors when iterating through the undefined object.
192+
S9.9_A1: FAIL_OK
193+
S9.9_A2: FAIL_OK
194+
195+
196+
187197
##################### SKIPPED TESTS #####################
188198

189199
# These tests take a looong time to run in debug mode.

0 commit comments

Comments
 (0)