OLD | NEW |
---|---|
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 | 6 |
7 #include "include/v8.h" | 7 #include "include/v8.h" |
8 #include "include/v8-experimental.h" | 8 #include "include/v8-experimental.h" |
9 | 9 |
10 #include "src/api.h" | 10 #include "src/api.h" |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 .FromJust()); | 106 .FromJust()); |
107 | 107 |
108 // Wrap f.barf + IC warmup. | 108 // Wrap f.barf + IC warmup. |
109 CompileRun(FN_WARMUP("barf", "f = new foo(); return f.barf")); | 109 CompileRun(FN_WARMUP("barf", "f = new foo(); return f.barf")); |
110 | 110 |
111 ExpectInt32("f = new foo(); f.bar", 123); | 111 ExpectInt32("f = new foo(); f.bar", 123); |
112 ExpectInt32("f = new foo(); f.barf", 123); // First call in this call site. | 112 ExpectInt32("f = new foo(); f.barf", 123); // First call in this call site. |
113 ExpectInt32("barf()", 124); // Call via warmed-up callsite. | 113 ExpectInt32("barf()", 124); // Call via warmed-up callsite. |
114 } | 114 } |
115 | 115 |
116 | |
117 void AddInternalFieldAccessor(v8::Isolate* isolate, | 116 void AddInternalFieldAccessor(v8::Isolate* isolate, |
118 v8::Local<v8::Template> templ, const char* name, | 117 v8::Local<v8::Template> templ, const char* name, |
119 int field_no) { | 118 int field_no, bool useUnsafeLoader) { |
120 auto builder = v8::experimental::FastAccessorBuilder::New(isolate); | 119 auto builder = v8::experimental::FastAccessorBuilder::New(isolate); |
121 builder->ReturnValue( | 120 |
122 builder->LoadInternalField(builder->GetReceiver(), field_no)); | 121 if (useUnsafeLoader) { |
122 builder->ReturnValue( | |
123 builder->LoadInternalFieldUnsafe(builder->GetReceiver(), field_no)); | |
124 } else { | |
125 builder->ReturnValue( | |
126 builder->LoadInternalField(builder->GetReceiver(), field_no)); | |
127 } | |
128 | |
123 templ->SetAccessorProperty(v8_str(name), | 129 templ->SetAccessorProperty(v8_str(name), |
124 v8::FunctionTemplate::NewWithFastHandler( | 130 v8::FunctionTemplate::NewWithFastHandler( |
125 isolate, NativePropertyAccessor, builder)); | 131 isolate, NativePropertyAccessor, builder)); |
126 } | 132 } |
127 | 133 |
128 | 134 |
129 // "Fast" accessor that accesses an internal field. | 135 // "Fast" accessor that accesses an internal field. |
130 TEST(FastAccessorWithInternalField) { | 136 TEST(FastAccessorWithInternalField) { |
131 // Crankshaft support for fast accessors is not implemented; crankshafted | 137 // Crankshaft support for fast accessors is not implemented; crankshafted |
132 // code uses the slow accessor which breaks this test's expectations. | 138 // code uses the slow accessor which breaks this test's expectations. |
133 v8::internal::FLAG_always_opt = false; | 139 v8::internal::FLAG_always_opt = false; |
134 LocalContext env; | 140 LocalContext env; |
135 v8::Isolate* isolate = env->GetIsolate(); | 141 v8::Isolate* isolate = env->GetIsolate(); |
136 v8::HandleScope scope(isolate); | 142 v8::HandleScope scope(isolate); |
137 | 143 |
138 v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate); | 144 v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate); |
139 foo->SetInternalFieldCount(3); | 145 foo->SetInternalFieldCount(3); |
140 AddInternalFieldAccessor(isolate, foo, "field0", 0); | 146 AddInternalFieldAccessor(isolate, foo, "field0", 0, false); |
141 AddInternalFieldAccessor(isolate, foo, "field1", 1); | 147 AddInternalFieldAccessor(isolate, foo, "field1", 1, false); |
142 AddInternalFieldAccessor(isolate, foo, "field2", 2); | 148 AddInternalFieldAccessor(isolate, foo, "field2", 2, false); |
143 | 149 |
144 // Create an instance w/ 3 internal fields, put in a string, a Smi, nothing. | 150 // Create an instance w/ 3 internal fields, put in a string, a Smi, nothing. |
145 v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked(); | 151 v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked(); |
152 obj->SetInternalField(0, v8_str("Hi there!")); | |
153 obj->SetInternalField(1, v8::Integer::New(isolate, 4321)); | |
154 CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); | |
155 | |
156 // Warmup. | |
157 CompileRun(FN_WARMUP("field0", "return obj.field0")); | |
158 CompileRun(FN_WARMUP("field1", "return obj.field1")); | |
159 CompileRun(FN_WARMUP("field2", "return obj.field2")); | |
160 | |
161 // Access fields. | |
162 ExpectString("field0()", "Hi there!"); | |
163 ExpectInt32("field1()", 4321); | |
164 ExpectUndefined("field2()"); | |
165 } | |
166 | |
167 // "Fast" accessor that accesses an internal field using the fast(er) but unsafe | |
168 // implementation of LoadInternalField. | |
169 TEST(FastAccessorLoadInternalFieldUnsafe) { | |
vogelheim
2016/07/27 09:50:56
nitpick: If we add the Unsafe-with-crash-when-FLAG
Alfonso
2016/07/28 14:39:13
Refactoring away the common part for the 3 tests.
| |
170 // Crankshaft support for fast accessors is not implemented; crankshafted | |
171 // code uses the slow accessor which breaks this test's expectations. | |
172 v8::internal::FLAG_always_opt = false; | |
173 LocalContext env; | |
174 v8::Isolate* isolate = env->GetIsolate(); | |
175 v8::HandleScope scope(isolate); | |
176 | |
177 v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate); | |
178 foo->SetInternalFieldCount(3); | |
179 AddInternalFieldAccessor(isolate, foo, "field0", 0, true); | |
180 AddInternalFieldAccessor(isolate, foo, "field1", 1, true); | |
181 AddInternalFieldAccessor(isolate, foo, "field2", 2, true); | |
182 | |
183 // Create an instance w/ 3 internal fields, put in a string, a Smi, nothing. | |
184 v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked(); | |
146 obj->SetInternalField(0, v8_str("Hi there!")); | 185 obj->SetInternalField(0, v8_str("Hi there!")); |
147 obj->SetInternalField(1, v8::Integer::New(isolate, 4321)); | 186 obj->SetInternalField(1, v8::Integer::New(isolate, 4321)); |
148 CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); | 187 CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); |
149 | 188 |
150 // Warmup. | 189 // Warmup. |
151 CompileRun(FN_WARMUP("field0", "return obj.field0")); | 190 CompileRun(FN_WARMUP("field0", "return obj.field0")); |
152 CompileRun(FN_WARMUP("field1", "return obj.field1")); | 191 CompileRun(FN_WARMUP("field1", "return obj.field1")); |
153 CompileRun(FN_WARMUP("field2", "return obj.field2")); | 192 CompileRun(FN_WARMUP("field2", "return obj.field2")); |
154 | 193 |
155 // Access fields. | 194 // Access fields. |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
377 // Callbacks: | 416 // Callbacks: |
378 CompileRun(FN_WARMUP("callbackint", "return obj.int")); | 417 CompileRun(FN_WARMUP("callbackint", "return obj.int")); |
379 ExpectInt32("callbackint()", 12345); | 418 ExpectInt32("callbackint()", 12345); |
380 | 419 |
381 CompileRun(FN_WARMUP("callbackstr", "return obj.str")); | 420 CompileRun(FN_WARMUP("callbackstr", "return obj.str")); |
382 ExpectString("callbackstr()", kApiCallbackStringValue); | 421 ExpectString("callbackstr()", kApiCallbackStringValue); |
383 | 422 |
384 CompileRun(FN_WARMUP("callbackparam", "return obj.param")); | 423 CompileRun(FN_WARMUP("callbackparam", "return obj.param")); |
385 ExpectInt32("callbackparam()", 1000); | 424 ExpectInt32("callbackparam()", 1000); |
386 } | 425 } |
OLD | NEW |