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 "src/api.h" | 5 #include "src/api.h" |
6 #include "src/api-natives.h" | 6 #include "src/api-natives.h" |
7 #include "src/assert-scope.h" | 7 #include "src/assert-scope.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/factory.h" | 10 #include "src/factory.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 namespace v8 { | 28 namespace v8 { |
29 | 29 |
30 namespace { | 30 namespace { |
31 struct RawBuffer { | 31 struct RawBuffer { |
32 const byte* start; | 32 const byte* start; |
33 const byte* end; | 33 const byte* end; |
34 size_t size() { return static_cast<size_t>(end - start); } | 34 size_t size() { return static_cast<size_t>(end - start); } |
35 }; | 35 }; |
36 | 36 |
37 | |
38 RawBuffer GetRawBufferArgument( | 37 RawBuffer GetRawBufferArgument( |
39 ErrorThrower& thrower, const v8::FunctionCallbackInfo<v8::Value>& args) { | 38 ErrorThrower& thrower, const v8::FunctionCallbackInfo<v8::Value>& args) { |
40 if (args.Length() < 1) { | 39 if (args.Length() < 1) { |
41 thrower.Error("Argument 0 must be an array buffer"); | 40 thrower.Error("Argument 0 must be an array buffer"); |
42 return {nullptr, nullptr}; | 41 return {nullptr, nullptr}; |
43 } | 42 } |
44 | 43 |
45 const byte* start = nullptr; | 44 const byte* start = nullptr; |
46 const byte* end = nullptr; | 45 const byte* end = nullptr; |
47 | 46 |
(...skipping 22 matching lines...) Expand all Loading... |
70 if (start == nullptr || end == start) { | 69 if (start == nullptr || end == start) { |
71 thrower.Error("ArrayBuffer argument is empty"); | 70 thrower.Error("ArrayBuffer argument is empty"); |
72 } | 71 } |
73 } else { | 72 } else { |
74 thrower.Error("Argument 0 must be an ArrayBuffer or Uint8Array"); | 73 thrower.Error("Argument 0 must be an ArrayBuffer or Uint8Array"); |
75 } | 74 } |
76 | 75 |
77 return {start, end}; | 76 return {start, end}; |
78 } | 77 } |
79 | 78 |
80 | |
81 void VerifyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | 79 void VerifyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
82 HandleScope scope(args.GetIsolate()); | 80 HandleScope scope(args.GetIsolate()); |
83 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 81 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
84 ErrorThrower thrower(isolate, "WASM.verifyModule()"); | 82 ErrorThrower thrower(isolate, "WASM.verifyModule()"); |
85 | 83 |
86 RawBuffer buffer = GetRawBufferArgument(thrower, args); | 84 RawBuffer buffer = GetRawBufferArgument(thrower, args); |
87 if (thrower.error()) return; | 85 if (thrower.error()) return; |
88 | 86 |
89 i::Zone zone(isolate->allocator()); | 87 i::Zone zone(isolate->allocator()); |
90 internal::wasm::ModuleResult result = | 88 internal::wasm::ModuleResult result = |
91 internal::wasm::DecodeWasmModule(isolate, &zone, buffer.start, buffer.end, | 89 internal::wasm::DecodeWasmModule(isolate, &zone, buffer.start, buffer.end, |
92 true, internal::wasm::kWasmOrigin); | 90 true, internal::wasm::kWasmOrigin); |
93 | 91 |
94 if (result.failed()) { | 92 if (result.failed()) { |
95 thrower.Failed("", result); | 93 thrower.Failed("", result); |
96 } | 94 } |
97 | 95 |
98 if (result.val) delete result.val; | 96 if (result.val) delete result.val; |
99 } | 97 } |
100 | 98 |
101 | |
102 void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) { | 99 void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) { |
103 HandleScope scope(args.GetIsolate()); | 100 HandleScope scope(args.GetIsolate()); |
104 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 101 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
105 ErrorThrower thrower(isolate, "WASM.verifyFunction()"); | 102 ErrorThrower thrower(isolate, "WASM.verifyFunction()"); |
106 | 103 |
107 RawBuffer buffer = GetRawBufferArgument(thrower, args); | 104 RawBuffer buffer = GetRawBufferArgument(thrower, args); |
108 if (thrower.error()) return; | 105 if (thrower.error()) return; |
109 | 106 |
110 internal::wasm::FunctionResult result; | 107 internal::wasm::FunctionResult result; |
111 { | 108 { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 result.val->Instantiate(isolate, ffi, memory); | 192 result.val->Instantiate(isolate, ffi, memory); |
196 | 193 |
197 if (!object.is_null()) { | 194 if (!object.is_null()) { |
198 args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked())); | 195 args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked())); |
199 } | 196 } |
200 } | 197 } |
201 | 198 |
202 if (result.val) delete result.val; | 199 if (result.val) delete result.val; |
203 } | 200 } |
204 | 201 |
205 | |
206 void InstantiateModuleFromAsm(const v8::FunctionCallbackInfo<v8::Value>& args) { | 202 void InstantiateModuleFromAsm(const v8::FunctionCallbackInfo<v8::Value>& args) { |
207 HandleScope scope(args.GetIsolate()); | 203 HandleScope scope(args.GetIsolate()); |
208 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 204 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
209 ErrorThrower thrower(isolate, "WASM.instantiateModuleFromAsm()"); | 205 ErrorThrower thrower(isolate, "WASM.instantiateModuleFromAsm()"); |
210 | 206 |
211 if (!args[0]->IsString()) { | 207 if (!args[0]->IsString()) { |
212 thrower.Error("Asm module text should be a string"); | 208 thrower.Error("Asm module text should be a string"); |
213 return; | 209 return; |
214 } | 210 } |
215 | 211 |
(...skipping 11 matching lines...) Expand all Loading... |
227 | 223 |
228 auto module = TranslateAsmModule(&info, foreign, &thrower); | 224 auto module = TranslateAsmModule(&info, foreign, &thrower); |
229 if (module == nullptr) { | 225 if (module == nullptr) { |
230 return; | 226 return; |
231 } | 227 } |
232 | 228 |
233 InstantiateModuleCommon(args, module->Begin(), module->End(), &thrower, | 229 InstantiateModuleCommon(args, module->Begin(), module->End(), &thrower, |
234 internal::wasm::kAsmJsOrigin); | 230 internal::wasm::kAsmJsOrigin); |
235 } | 231 } |
236 | 232 |
237 | |
238 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | 233 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
239 HandleScope scope(args.GetIsolate()); | 234 HandleScope scope(args.GetIsolate()); |
240 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 235 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
241 ErrorThrower thrower(isolate, "WASM.instantiateModule()"); | 236 ErrorThrower thrower(isolate, "WASM.instantiateModule()"); |
242 | 237 |
243 RawBuffer buffer = GetRawBufferArgument(thrower, args); | 238 RawBuffer buffer = GetRawBufferArgument(thrower, args); |
244 if (buffer.start == nullptr) return; | 239 if (buffer.start == nullptr) return; |
245 | 240 |
246 InstantiateModuleCommon(args, buffer.start, buffer.end, &thrower, | 241 InstantiateModuleCommon(args, buffer.start, buffer.end, &thrower, |
247 internal::wasm::kWasmOrigin); | 242 internal::wasm::kWasmOrigin); |
248 } | 243 } |
249 } // namespace | 244 } // namespace |
250 | 245 |
251 | |
252 // TODO(titzer): we use the API to create the function template because the | 246 // TODO(titzer): we use the API to create the function template because the |
253 // internal guts are too ugly to replicate here. | 247 // internal guts are too ugly to replicate here. |
254 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, | 248 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, |
255 FunctionCallback func) { | 249 FunctionCallback func) { |
256 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate); | 250 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate); |
257 Local<FunctionTemplate> local = FunctionTemplate::New(isolate, func); | 251 Local<FunctionTemplate> local = FunctionTemplate::New(isolate, func); |
258 return v8::Utils::OpenHandle(*local); | 252 return v8::Utils::OpenHandle(*local); |
259 } | 253 } |
260 | 254 |
261 | |
262 namespace internal { | 255 namespace internal { |
263 static Handle<String> v8_str(Isolate* isolate, const char* str) { | 256 static Handle<String> v8_str(Isolate* isolate, const char* str) { |
264 return isolate->factory()->NewStringFromAsciiChecked(str); | 257 return isolate->factory()->NewStringFromAsciiChecked(str); |
265 } | 258 } |
266 | 259 |
267 | |
268 static void InstallFunc(Isolate* isolate, Handle<JSObject> object, | 260 static void InstallFunc(Isolate* isolate, Handle<JSObject> object, |
269 const char* str, FunctionCallback func) { | 261 const char* str, FunctionCallback func) { |
270 Handle<String> name = v8_str(isolate, str); | 262 Handle<String> name = v8_str(isolate, str); |
271 Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); | 263 Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); |
272 Handle<JSFunction> function = | 264 Handle<JSFunction> function = |
273 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); | 265 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); |
274 PropertyAttributes attributes = | 266 PropertyAttributes attributes = |
275 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 267 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
276 JSObject::AddProperty(object, name, function, attributes); | 268 JSObject::AddProperty(object, name, function, attributes); |
277 } | 269 } |
278 | 270 |
279 | |
280 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { | 271 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { |
281 // Setup wasm function map. | 272 // Setup wasm function map. |
282 Handle<Context> context(global->native_context(), isolate); | 273 Handle<Context> context(global->native_context(), isolate); |
283 InstallWasmFunctionMap(isolate, context); | 274 InstallWasmFunctionMap(isolate, context); |
284 | 275 |
285 // Bind the WASM object. | 276 // Bind the WASM object. |
286 Factory* factory = isolate->factory(); | 277 Factory* factory = isolate->factory(); |
287 Handle<String> name = v8_str(isolate, "Wasm"); | 278 Handle<String> name = v8_str(isolate, "Wasm"); |
288 Handle<JSFunction> cons = factory->NewFunction(name); | 279 Handle<JSFunction> cons = factory->NewFunction(name); |
289 JSFunction::SetInstancePrototype( | 280 JSFunction::SetInstancePrototype( |
(...skipping 13 matching lines...) Expand all Loading... |
303 { | 294 { |
304 // Add the Wasm.experimentalVersion property. | 295 // Add the Wasm.experimentalVersion property. |
305 Handle<String> name = v8_str(isolate, "experimentalVersion"); | 296 Handle<String> name = v8_str(isolate, "experimentalVersion"); |
306 PropertyAttributes attributes = | 297 PropertyAttributes attributes = |
307 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 298 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
308 Handle<Smi> value = Handle<Smi>(Smi::FromInt(wasm::kWasmVersion), isolate); | 299 Handle<Smi> value = Handle<Smi>(Smi::FromInt(wasm::kWasmVersion), isolate); |
309 JSObject::AddProperty(wasm_object, name, value, attributes); | 300 JSObject::AddProperty(wasm_object, name, value, attributes); |
310 } | 301 } |
311 } | 302 } |
312 | 303 |
313 | |
314 void WasmJs::InstallWasmFunctionMap(Isolate* isolate, Handle<Context> context) { | 304 void WasmJs::InstallWasmFunctionMap(Isolate* isolate, Handle<Context> context) { |
315 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { | 305 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { |
316 // TODO(titzer): Move this to bootstrapper.cc?? | 306 // TODO(titzer): Move this to bootstrapper.cc?? |
317 // TODO(titzer): Also make one for strict mode functions? | 307 // TODO(titzer): Also make one for strict mode functions? |
318 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); | 308 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); |
319 | 309 |
320 InstanceType instance_type = prev_map->instance_type(); | 310 InstanceType instance_type = prev_map->instance_type(); |
321 int internal_fields = JSObject::GetInternalFieldCount(*prev_map); | 311 int internal_fields = JSObject::GetInternalFieldCount(*prev_map); |
322 CHECK_EQ(0, internal_fields); | 312 CHECK_EQ(0, internal_fields); |
323 int pre_allocated = | 313 int pre_allocated = |
324 prev_map->GetInObjectProperties() - prev_map->unused_property_fields(); | 314 prev_map->GetInObjectProperties() - prev_map->unused_property_fields(); |
325 int instance_size; | 315 int instance_size; |
326 int in_object_properties; | 316 int in_object_properties; |
327 JSFunction::CalculateInstanceSizeHelper(instance_type, internal_fields + 1, | 317 JSFunction::CalculateInstanceSizeHelper(instance_type, internal_fields + 1, |
328 0, &instance_size, | 318 0, &instance_size, |
329 &in_object_properties); | 319 &in_object_properties); |
330 | 320 |
331 int unused_property_fields = in_object_properties - pre_allocated; | 321 int unused_property_fields = in_object_properties - pre_allocated; |
332 Handle<Map> map = Map::CopyInitialMap( | 322 Handle<Map> map = Map::CopyInitialMap( |
333 prev_map, instance_size, in_object_properties, unused_property_fields); | 323 prev_map, instance_size, in_object_properties, unused_property_fields); |
334 | 324 |
335 context->set_wasm_function_map(*map); | 325 context->set_wasm_function_map(*map); |
336 } | 326 } |
337 } | 327 } |
338 | 328 |
339 } // namespace internal | 329 } // namespace internal |
340 } // namespace v8 | 330 } // namespace v8 |
OLD | NEW |