⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 builtins-ia32.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:////     * Redistributions of source code must retain the above copyright//       notice, this list of conditions and the following disclaimer.//     * Redistributions in binary form must reproduce the above//       copyright notice, this list of conditions and the following//       disclaimer in the documentation and/or other materials provided//       with the distribution.//     * Neither the name of Google Inc. nor the names of its//       contributors may be used to endorse or promote products derived//       from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include "v8.h"#include "codegen-inl.h"#include "debug.h"#include "runtime.h"namespace v8 { namespace internal {#define __ masm->void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {  // TODO(1238487): Don't pass the function in a static variable.  ExternalReference passed = ExternalReference::builtin_passed_function();  __ mov(Operand::StaticVariable(passed), edi);  // The actual argument count has already been loaded into register  // eax, but JumpToBuiltin expects eax to contain the number of  // arguments including the receiver.  __ inc(eax);  __ JumpToBuiltin(ExternalReference(id));}void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {  // ----------- S t a t e -------------  //  -- eax: number of arguments  //  -- edi: constructor function  // -----------------------------------  // Enter an internal frame.  __ EnterInternalFrame();  // Store a smi-tagged arguments count on the stack.  __ shl(eax, kSmiTagSize);  __ push(eax);  // Push the function to invoke on the stack.  __ push(edi);  // Try to allocate the object without transitioning into C code. If any of the  // preconditions is not met, the code bails out to the runtime call.  Label rt_call, allocated;  if (FLAG_inline_new) {    Label undo_allocation;    ExternalReference debug_step_in_fp =        ExternalReference::debug_step_in_fp_address();    __ cmp(Operand::StaticVariable(debug_step_in_fp), Immediate(0));    __ j(not_equal, &rt_call);    // Check that function is not a Smi.    __ test(edi, Immediate(kSmiTagMask));    __ j(zero, &rt_call);    // Check that function is a JSFunction    __ mov(eax, FieldOperand(edi, JSFunction::kMapOffset));    __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset));    __ cmp(eax, JS_FUNCTION_TYPE);    __ j(not_equal, &rt_call);    // Verified that the constructor is a JSFunction.    // Load the initial map and verify that it is in fact a map.    // edi: constructor    __ mov(eax, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));    // Will both indicate a NULL and a Smi    __ test(eax, Immediate(kSmiTagMask));    __ j(zero, &rt_call);    // edi: constructor    // eax: initial map (if proven valid below)    __ mov(ebx, FieldOperand(eax, JSFunction::kMapOffset));    __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));    __ cmp(ebx, MAP_TYPE);    __ j(not_equal, &rt_call);    // Check that the constructor is not constructing a JSFunction (see comments    // in Runtime_NewObject in runtime.cc). In which case the initial map's    // instance type would be JS_FUNCTION_TYPE.    // edi: constructor    // eax: initial map    __ movzx_b(ebx, FieldOperand(eax, Map::kInstanceTypeOffset));    __ cmp(ebx, JS_FUNCTION_TYPE);    __ j(equal, &rt_call);    // Now allocate the JSObject on the heap.    // edi: constructor    // eax: initial map    __ movzx_b(edi, FieldOperand(eax, Map::kInstanceSizeOffset));    // Make sure that the maximum heap object size will never cause us    // problem here, because it is always greater than the maximum    // instance size that can be represented in a byte.    ASSERT(Heap::MaxHeapObjectSize() >= (1 << kBitsPerByte));    ExternalReference new_space_allocation_top =        ExternalReference::new_space_allocation_top_address();    __ mov(ebx, Operand::StaticVariable(new_space_allocation_top));    __ add(edi, Operand(ebx));  // Calculate new top    ExternalReference new_space_allocation_limit =        ExternalReference::new_space_allocation_limit_address();    __ cmp(edi, Operand::StaticVariable(new_space_allocation_limit));    __ j(greater_equal, &rt_call);    // Allocated the JSObject, now initialize the fields.    // eax: initial map    // ebx: JSObject    // edi: start of next object    __ mov(Operand(ebx, JSObject::kMapOffset), eax);    __ mov(Operand(ecx), Factory::empty_fixed_array());    __ mov(Operand(ebx, JSObject::kPropertiesOffset), ecx);    __ mov(Operand(ebx, JSObject::kElementsOffset), ecx);    // Set extra fields in the newly allocated object.    // eax: initial map    // ebx: JSObject    // edi: start of next object    { Label loop, entry;      __ mov(Operand(edx), Factory::undefined_value());      __ lea(ecx, Operand(ebx, JSObject::kHeaderSize));      __ jmp(&entry);      __ bind(&loop);      __ mov(Operand(ecx, 0), edx);      __ add(Operand(ecx), Immediate(kPointerSize));      __ bind(&entry);      __ cmp(ecx, Operand(edi));      __ j(less, &loop);    }    // Mostly done with the JSObject. Add the heap tag and store the new top, so    // that we can continue and jump into the continuation code at any time from    // now on. Any failures need to undo the setting of the new top, so that the    // heap is in a consistent state and verifiable.    // eax: initial map    // ebx: JSObject    // edi: start of next object    __ or_(Operand(ebx), Immediate(kHeapObjectTag));    __ mov(Operand::StaticVariable(new_space_allocation_top), edi);    // Check if a properties array should be setup and allocate one if needed.    // Otherwise initialize the properties to the empty_fixed_array as well.    // eax: initial map    // ebx: JSObject    // edi: start of next object    __ movzx_b(edx, FieldOperand(eax, Map::kUnusedPropertyFieldsOffset));    __ test(edx, Operand(edx));    // Done if no unused properties are to be allocated.    __ j(zero, &allocated);    // Scale the number of elements by pointer size and add the header for    // FixedArrays to the start of the next object calculation from above.    // eax: initial map    // ebx: JSObject    // edi: start of next object (will be start of FixedArray)    // edx: number of elements in properties array    ASSERT(Heap::MaxHeapObjectSize() >           (FixedArray::kHeaderSize + 255*kPointerSize));    __ lea(ecx, Operand(edi, edx, times_4, FixedArray::kHeaderSize));    __ cmp(ecx, Operand::StaticVariable(new_space_allocation_limit));    __ j(greater_equal, &undo_allocation);    __ mov(Operand::StaticVariable(new_space_allocation_top), ecx);    // Initialize the FixedArray.    // ebx: JSObject    // edi: FixedArray    // edx: number of elements    // ecx: start of next object    __ mov(eax, Factory::fixed_array_map());    __ mov(Operand(edi, JSObject::kMapOffset), eax);  // setup the map    __ mov(Operand(edi, Array::kLengthOffset), edx);  // and length    // Initialize the fields to undefined.    // ebx: JSObject    // edi: FixedArray    // ecx: start of next object    { Label loop, entry;      __ mov(Operand(edx), Factory::undefined_value());      __ lea(eax, Operand(edi, FixedArray::kHeaderSize));      __ jmp(&entry);      __ bind(&loop);      __ mov(Operand(eax, 0), edx);      __ add(Operand(eax), Immediate(kPointerSize));      __ bind(&entry);      __ cmp(eax, Operand(ecx));      __ j(less, &loop);    }    // Store the initialized FixedArray into the properties field of    // the JSObject    // ebx: JSObject    // edi: FixedArray    __ or_(Operand(edi), Immediate(kHeapObjectTag));  // add the heap tag    __ mov(FieldOperand(ebx, JSObject::kPropertiesOffset), edi);    // Continue with JSObject being successfully allocated    // ebx: JSObject    __ jmp(&allocated);    // Undo the setting of the new top so that the heap is verifiable. For    // example, the map's unused properties potentially do not match the    // allocated objects unused properties.    // ebx: JSObject (previous new top)    __ bind(&undo_allocation);    __ xor_(Operand(ebx), Immediate(kHeapObjectTag));  // clear the heap tag    __ mov(Operand::StaticVariable(new_space_allocation_top), ebx);  }  // Allocate the new receiver object using the runtime call.  // edi: function (constructor)  __ bind(&rt_call);  // Must restore edi (constructor) before calling runtime.  __ mov(edi, Operand(esp, 0));  __ push(edi);  __ CallRuntime(Runtime::kNewObject, 1);  __ mov(ebx, Operand(eax));  // store result in ebx  // New object allocated.  // ebx: newly allocated object  __ bind(&allocated);  // Retrieve the function from the stack.  __ pop(edi);  // Retrieve smi-tagged arguments count from the stack.  __ mov(eax, Operand(esp, 0));  __ shr(eax, kSmiTagSize);  // Push the allocated receiver to the stack. We need two copies  // because we may have to return the original one and the calling  // conventions dictate that the called function pops the receiver.  __ push(ebx);  __ push(ebx);  // Setup pointer to last argument.  __ lea(ebx, Operand(ebp, StandardFrameConstants::kCallerSPOffset));  // Copy arguments and receiver to the expression stack.  Label loop, entry;  __ mov(ecx, Operand(eax));  __ jmp(&entry);  __ bind(&loop);  __ push(Operand(ebx, ecx, times_4, 0));  __ bind(&entry);  __ dec(ecx);  __ j(greater_equal, &loop);  // Call the function.  Label return_site;  ParameterCount actual(eax);  __ InvokeFunction(edi, actual, CALL_FUNCTION);  __ bind(&return_site);  // Restore context from the frame.  __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));  // If the result is an object (in the ECMA sense), we should get rid  // of the receiver and use the result; see ECMA-262 section 13.2.2-7  // on page 74.  Label use_receiver, exit;  // If the result is a smi, it is *not* an object in the ECMA sense.  __ test(eax, Immediate(kSmiTagMask));  __ j(zero, &use_receiver, not_taken);  // If the type of the result (stored in its map) is less than  // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense.  __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));  __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));  __ cmp(ecx, FIRST_JS_OBJECT_TYPE);  __ j(greater_equal, &exit, not_taken);  // Throw away the result of the constructor invocation and use the  // on-stack receiver as the result.  __ bind(&use_receiver);  __ mov(eax, Operand(esp, 0));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -